我正在使用neo4j 3.5,大约有900万个用户节点。我试图实现以下查询,但是时间太长了:
MATCH(用户:
User
)在哪里(users.username包含“ joe”或users.first_name CONTAINS“ joe”或users.last_name包含“ joe”) RETURN用户 LIMIT 30
我希望通过创建以下索引来利用neo4j 3.5的newe全文索引功能:
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
我认为这将与包含并返回其用户名,first_name或last_name包含joe的用户(例如:myjoe12,joe12、12joe,44joeseph等)相同,但是似乎返回的字段为{{1 }}正好或包含由空格分隔的joe
(例如:Joe B,Joe y1),我尝试在查询中使用joe
,但是只返回以joe*
开头的所有内容返回包含joe
或任何搜索词的所有内容。最好的方法是什么?
答案 0 :(得分:0)
到目前为止,我知道Neo4j的STARTS WITH
和ENDS WITH
的优化索引仅适用于非复合索引。
如果我阅读此docs paragraph,我的结论将是:您的900万用户将被一个一个地搜索,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
。参见regex operator docs和regex where docs
答案 1 :(得分:0)
对于全文模式索引,您似乎需要在查询中使用模糊搜索运算符~
,尽管您可能需要对得分进行一些过滤以确保您正在查看相关结果:
CALL db.index.fulltext.queryNodes('users', 'joe~')
YIELD node, score
WHERE score > .8
RETURN node.user_id