Cypher查询以搜索所有属性中的短语

时间:2016-05-19 15:55:45

标签: neo4j cypher

我尝试在Neo4j数据库中实现搜索时遇到了一个有趣的问题。我想在任何节点的属性中搜索某个短语(也允许部分匹配)。这必须是通用的,适用于所有节点类型和标签,因此我无法预先定义要搜索的属性列表。

为了理解这个问题,请考虑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

但是这个查询返回了一个空响应。没有错误,只是没有结果。

在尝试隔离问题时,我意识到查询 在以下情况下有效:

  1. 如果节点只有字符串属性(没有数字或布尔值)。
  2. 如果我使用完全匹配而不是正则表达式(where NOT(any(prop in keys(m) where m[prop] = "Hoffa")))。
  3. 如果我搜索特定属性(where NOT(any(prop in ['title','tagline'] where m[prop] =~ "(?i)The .*"))
  4. 似乎只有notany和正则表达式的组合打破了查询,而我却迷失了为什么会发生这种情况。

3 个答案:

答案 0 :(得分:4)

至少在neo4j 3.0中,STARTS WITH语法似乎更适合您的场景(但它区分大小写):

MATCH (m:Movie)
WHERE NONE(prop in keys(m) where TOSTRING(m[prop]) STARTS WITH "The ")
RETURN m;

答案 1 :(得分:1)

而不是使用

NOT (ANY

尝试

(NONE

答案 2 :(得分:0)

这对我有用

match (m:Movie)
where (any(prop in keys(m) where m[prop] =~ '.*the.*'))
return m