эффективность предложения where в cypher vs match

Я пытаюсь найти 10 сообщений, которые не понравились пользователю mike, используя cypher. Будет ли размещение предложения where с отношением NOT более эффективным, чем сопоставление с необязательным отношением, а затем проверка того, является ли это отношение нулевым в предложении where? В частности, я хочу убедиться, что он не будет выполнять эквивалент полного сканирования таблицы, и убедиться, что это масштабируемый запрос.

Вот что я использую

START user=node:node_auto_index(uname:"mike"), 
  posts=node:node_auto_index("postId:*") 
  WHERE not (user-[:LIKES]->posts) 
  RETURN posts SKIP 20 LIMIT 10;

Или я могу сделать что-то, где я отфильтровываю необязательную связь MATCH

START user=node:node_auto_index(uname="mike"),
  posts=node:node_auto_index("postId:*")
  MATCH user-[r?:LIKES]->posts  
  WHERE r IS NULL
  RETURN posts SKIP 100 LIMIT 10;

Некоторые быстрые тесты на консоли, кажется, показывают более высокую производительность при втором подходе. Правильно ли я предполагаю, что второй запрос быстрее? И если да, то почему?


person MonkeyBonkey    schedule 12.01.2013    source источник
comment
ваш второй запрос такой же, как и первый, за исключением значения SKIP 100. Разве где-то не должно быть предложения MATCH?   -  person ulkas    schedule 14.01.2013
comment
Дох, да, ошибка копирования и вставки. Теперь вопрос обновлен правильным 2-м примером.   -  person MonkeyBonkey    schedule 14.01.2013


Ответы (1)


Я думаю, что в первом запросе движок проходит через все postID узлы и вручную проверяет состояние not (user-[:LIKES]->posts) для каждого идентификатора сообщения, тогда как во втором примере (при условии, что вы используете по крайней мере v1.9.02) движок выбирает только узлы сообщений, которые на самом деле не подключены к пользователю. это просто оптимизация, при которой движок не проходит через все узлы postIDs.

по возможности всегда используйте в запросах предложение MATCH вместо WHERE и старайтесь опускать звездочку в объявлении START n=node:index('name:*')

person ulkas    schedule 14.01.2013
comment
Если я опущу звездочку в начальном предложении, каким будет альтернативный синтаксис? - person MonkeyBonkey; 14.01.2013
comment
это вопрос, связанный с дизайном вашего графика - если вы должны часто запрашивать этот запрос в реальном времени, возможно, было бы лучше изменить дизайн графа, пока вы не сможете выполнить запрос без звездочки. Однако иногда это невозможно. не могли бы вы предоставить нам ваш текущий дизайн БД и цели? - person ulkas; 15.01.2013
comment
это график пользователей и сообщений. Я использую auto_index для имени (для пользователей) и postId для сообщений, чтобы различать тип узла. Пользователи могут лайкать сообщения. Каждый день я хочу, чтобы пользователи просматривали случайный набор из сотен сообщений, которые им еще не понравились. Для иллюстрации предположим, что в день будут просматриваться миллионы сообщений в день по сравнению с 200 000 постов, которые понравились, 20 000 созданных постов и тысячами регистраций пользователей. - person MonkeyBonkey; 15.01.2013
comment
хм, не знаю, может быть, может помочь фильтрация по WHERE сразу после объявления START: START user=node:node_auto_index(uname="mike") MATCH user-[r:LIKES]->posts WITH MAX(Id(posts)) as mx,user START p=node:node_auto_index("postId:*") MATCH user-[r?:LIKE]-p WHERE Id(p)>mx AND Id(p)<(mx+100) and r is NULL RETURN p LIMIT 10;? - person ulkas; 16.01.2013
comment
исправить: START user=node:node_auto_index(uname="mike") MATCH user-[r:LIKES]->posts WITH MAX(Id(posts)) as mx,user START p=node:node_auto_index("postId:*") WHERE Id(p)>mx AND Id(p)<(mx+100) MATCH user-[r?:LIKE]-p WHERE r is NULL RETURN p LIMIT 10;? ` - person ulkas; 16.01.2013
comment
в любом случае, это звучит как работа для обычного sql db, или, точнее, нет необходимости использовать граф db, поскольку нет необходимости в обходах. может быть, neo4j не такой, как вы этого хотите. Я бы просто выбрал 1000 случайных сообщений, а затем отфильтровал бы первые 100 из этих сообщений, независимо от того, понравились они пользователю - это менее вычислительно, чем выбор всех сообщений, которые пользователю не нравятся, и отфильтровывать по ним 100. - person ulkas; 16.01.2013
comment
это просто один из вариантов использования. Другие варианты использования, которые у нас есть, для поиска рекомендаций и совместной фильтрации потребуют обхода графа. Пытаемся выяснить, сможем ли мы иметь одну базу данных графа, которая удовлетворяет всем нашим потребностям. - person MonkeyBonkey; 16.01.2013
comment
да, может быть, попробуйте создать новый вопрос для этой проблемы. этот вопрос уже вне внимания. - person ulkas; 17.01.2013