Neo4j Cypher - 比较属性值是否存在?

时间:2016-06-28 18:49:35

标签: neo4j cypher

我有一个大图,其中有节点代表人。它们都具有firstname和surname属性,有些具有middlename属性。我正在寻找可能代表同一个人的节点,所以我正在查看名称的不同排列。我目前正在比较姓氏和名字的第一个首字母[某些节点只有首字母],但是如果它们存在,我们无法弄清楚如何测试中间名。

我目前的查询是:

match (a:Author), (b:Author)
where
  a.surname=b.surname and
  ( a.firstname starts with 'A' and b.firstname starts with 'A')
return distinct a,b

我的理解是,OPTIONAL MATCH仅指模式,因此不会起作用。我无法找到一种方法来编写一个有意义的if语句。

对我来说,以编程方式执行此操作可能更有意义,而不是仅仅依赖于直接的Cypher查询,但我希望保持它非常简单,只需在Cypher中执行即可。

澄清我想要做的事情的一些例子。

示例1:

 Node 1:  firstname "John" middlename "Patrick" lastname "Smith" 
    Node 2: firstname "J" middlename "P" lastname "Smith" 
    Node 3: firstname "J" middlename "Q" lastname "Smith" 
    Node 4: firstname "J" lastname "Smith"

我想要一个将节点1,2和4返回为'匹配'的查询。

示例2:

Node 1:  firstname "Jane" lastname "Smith" 
Node 2: firstname "J" middlename "P" lastname "Smith" 
Node 3: firstname "J" middlename "Q" lastname "Smith" 
Node 4: firstname "J" lastname "Smith"

在这里,我想要所有4个节点,因为'规范'名字没有中间名。

1 个答案:

答案 0 :(得分:3)

我认为您需要以下内容:

match (a:Author), (b:Author)
where
  id(a) < id(b) and
  ( a.surname=b.surname) and
  ( a.firstname starts with 'A' and b.firstname starts with 'A') and
  ( a.middlename=b.middlename OR a.middlename IS NULL OR b.middlename IS NULL)
return a,b

How to work with null对于您正在处理的谜题是一个很好的参考。

编辑:让我们用一些伪码来分解它:

if (a.middlename is null) return true;
if (b.middlename is null) return true;
if (a.middlename is not null and b.middlename is not null and a.middlename!=b.middlename) return false;
if (a.middlename is not null and b.middlename is not null and a.middlename=b.middlename) return true;