Neo4j匹配模糊文本属性的快速方法

时间:2018-11-05 05:54:14

标签: indexing neo4j cypher alias

我有合理数量的节点(大约60,000)

(:Document {title:"A title"})

给出一个标题,我想找到匹配的节点(如果存在)。问题是我给的标题不一致。也就是说,有时新词的开头是大写,有时则全部用小写。有时将关键字与Kebab案例结合使用,有时将它们通常作为关键字编写。

为了弥补这一点,我使用apoc和给定标题与每个节点之间的Levenshtein距离,并且仅在节点低于某个阈值时才接受该节点作为匹配项:

MATCH (a:Document)
WHERE apoc.text.distance(a.title, "A title") < 10
RETURN a

扩展性不佳。目前,一次查找大约需要 700毫秒,这太慢了,因为它可能会增长到大约150,000个节点。

我当时想在节点的alias:[...]属性中存储/缓存备用标题的出现,并在所有别名上建立索引,但是我不知道在Neo4j中是否可以实现。

在庞大的节点数据库中,“模糊查找”标题的最快方法是什么?

2 个答案:

答案 0 :(得分:17)

在Neo4j 3.5(当前在beta03中)中,具有FTS(全文搜索)功能。

编辑:我在Neo4j中写了一篇有关FTS的详细博客文章:https://graphaware.com/neo4j/2019/01/11/neo4j-full-text-search-deep-dive.html

您可以使用Lucene Classic Query Parser Syntax查询文档。

创建索引:

CALL db.index.fulltext.createNodeIndex('documents', ['Document'], ['title','text'])

导入一些文档:

LOAD CSV WITH HEADERS FROM "file:///docs.csv" AS row
CREATE (n:Document) SET n = row

查询标题中包含“重费”的文档

CALL db.index.fulltext.queryNodes('documents', 'title: "heavy toll"')
YIELD node, score
RETURN node.title, score

╒══════════════════════════════════════════════════════════════════════╤══════════════════╕
│"node.title"                                                          │"score"           │
╞══════════════════════════════════════════════════════════════════════╪══════════════════╡
│"Among Deaths in 2016, a Heavy Toll in Pop Music - The New York Times"│3.7325966358184814│
└──────────────────────────────────────────────────────────────────────┴──────────────────┘

使用错字查询相同的标题:

CALL db.index.fulltext.queryNodes('documents', 'title: \\"heavy~ tall~\\"')
YIELD node, score
RETURN node.title, score

请注意转义引号=> \“,传递给基础解析器的字符串应包含引号,以便执行短语查询而不是布尔查询。

此外,字词旁边的tidle表示要使用Damarau-Levenshtein算法执行模糊搜索。

╒══════════════════════════════════════════════════════════════════════╤═════════════════════╕
│"node.title"                                                          │"score"              │
╞══════════════════════════════════════════════════════════════════════╪═════════════════════╡
│"Among Deaths in 2016, a Heavy Toll in Pop Music - The New York Times"│0.868073046207428    │
├──────────────────────────────────────────────────────────────────────┼─────────────────────┤
│"Prisons Run by C.E.O.s? Privatization Under Trump Could Carry a Heavy│0.4014900326728821   │
│ Price - The New York Times"                                          │                     │
├──────────────────────────────────────────────────────────────────────┼─────────────────────┤
│"‘All Talk,’ ‘No Action,’ Says Trump in Twitter Attack on Civil Rights│0.28181418776512146  │
│ Icon - The New York Times"                                           │                     │
├──────────────────────────────────────────────────────────────────────┼─────────────────────┤
│"Immigrants Head to Washington to Rally While Obama Is Still There - T│0.24634429812431335  │
│he New York Times"                                                    │                     │
├──────────────────────────────────────────────────────────────────────┼─────────────────────┤

答案 1 :(得分:0)

Christophe Willemsen在answer中指出的索引对于加快搜索速度必不可少,但我也想指出另一个历史性功能,它可能更适合您的“模糊搜索”:

Soundex是一种语音算法,用于通过声音(以英语发音)索引名称。