【发布时间】:2016-09-16 15:23:00
【问题描述】:
在我的Neo4j DB 中尝试实现搜索时遇到了一个有趣的问题。我想在任何节点的属性中搜索某个短语(也允许部分匹配)。这必须是通用的并且适用于所有节点类型和标签,所以我不能有一个预定义的属性列表来搜索。
为了理解这个问题,请考虑捆绑在 Neo4j 浏览器 (:play movie graph) 中的著名 Movie DB 教程:假设我要搜索标签为 Movie 且属性以“The”开头的节点.我的第一个想法是:
match (m:Movie)
where (any(prop in keys(m) where m[prop] starts with "The"))
return m
这当然会引发错误,因为其中一个属性是数字而不是字符串。使用toString 对我没有帮助,因为在我的数据库中,一些属性是布尔值,而布尔值不会响应toString。
我的下一个尝试是使用正则表达式,这也更适合搜索,因为我可以使它不区分大小写并且总体上更健壮。所以我这样做了:
match (m:Movie)
where (any(prop in keys(m) where m[prop] =~ "(?i)The .*"))
return m
它成功了!我得到了所有标题或标语都以“The”开头的电影。并且有很多欢乐。
但现在是棘手的部分。我的搜索还需要提供对搜索的否定,即所有不具有任何以“The”开头的属性的电影。我显然试过了:
match (m:Movie)
where NOT (any(prop in keys(m) where m[prop] =~ "(?i)The .*"))
return m
但是这个查询返回了一个空响应。没有错误,只是没有结果。
在尝试隔离问题时,我意识到查询确实在以下情况下起作用:
- 如果节点只有字符串属性(没有数字或布尔值)。
- 如果我使用完全匹配而不是正则表达式 (
where NOT(any(prop in keys(m) where m[prop] = "Hoffa")))。 - 如果我搜索特定属性 (
where NOT(any(prop in ['title','tagline'] where m[prop] =~ "(?i)The .*")))
似乎只有not、any 和正则表达式的组合会破坏查询,我不知道为什么会发生这种情况。
【问题讨论】: