Neo4j自由文本搜索结合关系查询

时间:2019-04-14 11:20:52

标签: neo4j full-text-search full-text-indexing

我看到Neo4j有Indexes to support full-text search。但是我在文档中找不到有关如何在常规关系查询中使用此功能的示例。

例如,我具有以下结构:(:User)->[:Wrote]->(:Review)->[:Reviewing]->(:Movie)

我要搜索具有全文搜索功能的评论,但仅针对特定用户。因此,用户“ 123”要搜索其所有带有“出色表演”的评论。因此,搜索用户的评论将为MATCH (:User { id: 123 })-[w]->(review)。在搜索带有“ great”和“ acting”一词的评论时,将是CALL db.index.fulltext.queryNodes("reviews", "great acting")

我不知道如何将两者与AND逻辑结合在一起。

编辑
我认为我可以做以下事情:

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

问题是,我可能有数以百万计的评论,其中包含“出色”或“表演”,而相关用户的评论可能不超过10则。听起来效率不高。

2 个答案:

答案 0 :(得分:1)

在这种情况下,全文搜索不会对性能有所帮助,因为这会选择所有包含“出色表演”的评论(其中可能有很多很棒的评论),然后您需要过滤属于相关用户的用户。

这远不及匹配相关用户的评论(后者应该相对要少得多),然后过滤出“出色表演”一词的效果。

您可以在WHERE子句中使用CONTAINS关键字,以确保属性包含给定的子字符串,如Raj的回答(尽管这是区分大小写的):

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

您也可以在此上创建索引,但是如果不用于此处查找,而是从用户节点开始,则效率会更高(您可以对查询进行解释,以确定使用哪些索引来查找起始位置)节点)。

如果您需要不区分大小写的关键字搜索,则可以使用=~ regex operator,尽管它没有索引支持。例如:

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

答案 1 :(得分:0)

在这种情况下不知道如何使用全文本搜索,但在这种情况下,我认为您可以使用带有CONTAINS谓词的单个属性索引。

如果您要搜索节点的单个属性,则可以对该属性建立索引并使用CONTAINS谓词进行搜索。

创建索引:

CREATE INDEX ON :Review(text)

搜索查询:

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

PS:

另一种方法可能是先使用全文本搜索来搜索评论节点,然后通过在上述查询中进行匹配为用户过滤这些评论节点。我怀疑这样做会不会改善性能。