【问题标题】:Neo4j Cypher - Compare property values if they exist?Neo4j Cypher - 比较属性值(如果存在)?
【发布时间】:2016-06-28 18:49:34
【问题描述】:

我有一个大图,其中有代表人的节点。它们都有名字和姓氏属性,有些有中间名属性。我正在寻找可能代表同一个人的节点,因此正在研究名称的不同排列。我目前正在比较姓氏和名字的首字母[有些节点只有首字母],但不知道如何测试中间名(如果存在)。

我目前的查询是:

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 个节点,因为“规范”名称没有中间名。

【问题讨论】:

  • 您可能想要更清楚地阐明您正在尝试做什么,因为“无法弄清楚如何测试中间名(如果存在)”导致我告诉您使用 EXISTS并为它投票。
  • 谢谢,希望我的扩展示例能更好地阐明。 FWIW,我没有对你投反对票。对我来说,您的评论表明我没有清楚地解释我试图解决的问题。

标签: neo4j cypher


【解决方案1】:

我认为您需要以下内容:

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;

【讨论】:

  • 这种说法背后有什么原因吗?目前我无法自己测试。
  • 根据我对有些难以理解的要求的理解,OP想要比较都有中间名的人和没有中间名的人。您添加的最后一个子句基本上匹配每个人,除非他们有完全相同的中间名(奇怪?)或者其中一个是 nil。
  • 如果符合 OP 的模糊要求,您可以这样做。
  • @joslinm 是对的,这不是合理的逻辑。如果 a.middlename 为 null 或 b.middlename 为 null 或它们完全相等,a.middlename=b.middlename OR a.middlename IS NULL OR b.middlename IS NULL 将返回 true,这与伪代码示例相矛盾。
  • 转念一想,我认为我错了。我的回答做同样的事情,只是我没有做太多的比较。道歉!我已经删除了我的答案。您只需在 WHERE 子句中添加 id(a) &lt; id(b) 即可改进您的答案,这样您就不会进行重复比较。
猜你喜欢
  • 2017-05-12
  • 1970-01-01
  • 2017-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-22
  • 1970-01-01
相关资源
最近更新 更多