Neo4j свободный текстовый поиск в сочетании с запросом отношения - PullRequest
2 голосов
/ 14 апреля 2019

Я вижу, что у Neo4j есть индексы для поддержки полнотекстового поиска . Но я не могу найти примеры в документации о том, как использовать эту возможность с запросом регулярных отношений.

Например, у меня есть следующая структура: (:User)->[:Wrote]->(:Review)->[:Reviewing]->(:Movie)

Я хочу искать Обзоры с возможностью полнотекстового поиска, но только для конкретного пользователя. Поэтому пользователь «123» хочет искать во всех своих обзорах «отличную игру». Поэтому поиск по отзывам пользователей будет MATCH (:User { id: 123 })-[w]->(review). При поиске отзывов со словами «отлично» и «актерское мастерство» будет CALL db.index.fulltext.queryNodes("reviews", "great acting")

Чего я не могу понять, так это как объединить два с логикой AND.

EDIT
Я подумал, что могу сделать следующее:

CALL db.index.fulltext.queryNodes("reviews", "great acting") YIELD node as reviews
MATCH (:User { id: 123 })-[w]->(reviews)

Дело в том, что у меня могут быть миллионы отзывов с "отличным" или "действующим", в то время как у соответствующего пользователя, вероятно, не более 10-ти обзоров. Звучит не очень эффективно.

Ответы [ 2 ]

1 голос
/ 16 апреля 2019

В этом конкретном случае полнотекстовый поиск не поможет справиться с производительностью, так как при этом будут выбраны все обзоры, содержащие «отличную игру» (которых, вероятно, очень много), а затем вам нужно будет отфильтроватьдля тех, кто принадлежит рассматриваемому пользователю.

Это гораздо менее эффективно, чем сопоставление с отзывами рассматриваемого пользователя (которых должно быть сравнительно гораздо меньше), а затем отфильтровывать их по слову «великий».действующих '.

Вы можете использовать ключевое слово CONTAINS в предложении WHERE, чтобы убедиться, что свойство содержит заданную подстроку, как в ответе Радж (хотя это чувствительно к регистру):

MATCH (:User{ id: 123 })->[:Wrote]->(review:Review)->[:Reviewing]->(:Movie) 
WHERE review.text CONTAINS 'great acting'
...

ВыМожно также создать индекс для этого, хотя это гораздо более эффективно, если он не используется для поиска здесь, а вместо этого начинается с пользовательского узла (вы можете ОБЪЯСНИТЬ запрос, чтобы определить, какие индексы используются для поиска начального узла (-ов)).

Если вам нужен поиск ключевых слов без учета регистра, вы можете использовать оператор = ~ regex для этого, хотя это не поддерживается индексами.Например:

MATCH (:User{ id: 123 })->[:Wrote]->(review:Review)->[:Reviewing]->(:Movie) 
WHERE review.text =~ '(?i).*great acting.*'
...
0 голосов
/ 14 апреля 2019

Не знаю, как использовать полнотекстовый поиск в этом случае, но я думаю, что вы можете использовать один индекс свойства с предикатом CONTAINS в этом случае.

Если вы выполняете поиск по одному свойству узла , вы можете проиндексировать это свойство и выполнить поиск с предикатом CONTAINS.

Создать индекс:

CREATE INDEX ON :Review(text)

Поисковый запрос:

MATCH (:User{ id: 123 })->[:Wrote]->(review:Review)->[:Reviewing]->(:Movie) 
WHERE review.text CONTAINS 'love'

P.S .:

Другим подходом может быть сначала поиск узлов просмотра с использованием полнотекстового поиска, а затем фильтрация этих узлов просмотра для пользователя путем сопоставления в приведенном выше запросе. Я сомневаюсь, что это улучшит производительность.

...