Использование полнотекстовой индексации Neo4j для запросов Contains - PullRequest
0 голосов
/ 20 февраля 2019

Я использую neo4j 3.5, и у меня около 9 миллионов пользовательских узлов.Я пытался реализовать следующий запрос, но он занимал слишком много времени:

MATCH (users: User) WHERE (users.username СОДЕРЖИТ "joe" ИЛИ users.first_name CONTAINS "joe"ИЛИ users.last_name СОДЕРЖИТ" joe ") ВОЗВРАЩАЙТЕ пользователей LIMIT 30

Я надеялся воспользоваться новой функцией полнотекстовой индексации neo4j 3.5, создав следующий индекс:

CALL db.index.fulltext.createNodeIndex('users', ['User'], ['username', 'first_name', 'last_name'])

, а затем запрашивать базу данных следующим образом:

CALL db.index.fulltext.queryNodes('users', joe)
YIELD node
RETURN node.user_id

Я думал, что это будет работать так же, как содержит и возвращает пользователей, чьи username, first_name или last_name содержат joe (например: myjoe12, joe12, 12joe, 44joeseph,и т. д.), но, похоже, возвращаются пользователи, чьи поля joe точно или содержат joe, разделенные пробелами (например: Joe B, Joe y1), я попытался использовать joe* в запросе, но он возвращает только всеначиная с joe, я хочу вернуть все, что содержит joe или любой другой поисковый запрос.Как лучше всего это сделать?

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

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

CALL db.index.fulltext.queryNodes('users', 'joe~')
YIELD node, score
WHERE score > .8
RETURN node.user_id
0 голосов
/ 20 февраля 2019

Скорость выпуска / Индекс:

Насколько я знаю, Neo4j имеет оптимизированный индекс для STARTS WITH & ENDS WITH только для НЕ составных индексов.

Если я прочитал это docs абзац , мой вывод будет таким: ваши 9 миллионов пользователей будут подвергаться поиску один за другим, neo4j не использует индекс для вашего запроса.Что делает этот запрос очень медленным.

Ответ на ваш вопрос:

Я хочу вернуть все, что содержит Joe или любой другой поисковый запрос.

Вы, вероятно, ищете поиск по регулярному выражению (это также медленный и не поиск по индексу и не рекомендуется):

Пример запроса на основе вашего запроса:

MATCH (users:User)
WHERE (users.username =~ "(?i).*joe.*" OR users.first_name =~ "(?i).*joe.*" OR users.last_name =~ "(?i).*joe.*")
RETURN users
LIMIT 30

Объяснение для (?i)это означает, что регистр не учитывается, поэтому Joe или joe будут сопоставлены.См. регулярные выражения для операторов и регулярные выражения, где документы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...