Cypher - 通过其连接节点的属性匹配节点?

Posted

技术标签:

【中文标题】Cypher - 通过其连接节点的属性匹配节点?【英文标题】:Cypher - Match node by properties of its connected nodes? 【发布时间】:2020-09-11 16:39:39 【问题描述】:

我们构建了一个 Neo4j 模型,其中每个“实体”节点都链接到一组“属性”节点,每个节点都带有一个“标签”和一个“值”属性。

在给定“标签”/“值”属性的情况下,获取具有所有请求的“属性”邻居的“实体”节点的(最有效的)Cypher 请求是什么?

【问题讨论】:

【参考方案1】:

假设您使用HAS 关系类型,并且您传递了一个props parameter,其中包含以下示例格式的所需标签/值对列表:[['foo', 123], ['bar', true], ['foo', 234], ['baba', 'black sheep']],此查询应该可以工作:

MATCH (e:Entity)
WHERE ALL(p IN $props WHERE SIZE([(e)-[:HAS]->(a:Attrib) WHERE a[p[0]] = p[1] | 1]) > 0)
RETURN e

[更新]

返回的e 节点必须具有相关的Attrib 节点,其中包含props 参数中的所有属性名称和值对。

pattern comprehension 必须指定一个投影,所以这个查询只使用 1 作为投影,因为我们不关心生成列表的内容。我们只关心列表的测试大小。

要使用示例props 参数值测试上述查询,首先创建一些合适的节点和关系。例如:

CREATE (e:Entity id: 1),
  (e)-[:HAS]->(:Attrib id: 22, foo: 123, bar: true),
  (e)-[:HAS]->(:Attrib id: 33, baba: 'black sheep'),
  (e)-[:HAS]->(:Attrib id: 44, foo: 234)

【讨论】:

唉!它不是。这就是我尝试过的::params props: [["Name": "Name_1"]] 但是当我尝试启动请求时:Expected Long(0) to be a org.neo4j.values.storable.TextValue, but it was a org.neo4j.values.storable.LongValue 现在你能解释一下a[p[0]] = p[1] | 1]吗? 非常感谢,先生。有用。谢谢。现在,你能看出我自己提出的答案有什么问题吗(见下文)?然后,为什么上面的“Expected Long(0) to be a org.neo4j.values.storable.TextValue, but it was a org.neo4j.values.storable.LongValue”错误? 好的,现在我明白了您的答案和我的答案之间的区别:在我的问题中,实体创建模式类似于:CREATE (e:Entity id: 1), (f:Entity id: 2), (e)-[:HAS]->(:Attribute id: 10, label: 'color', value: 'blue'), (e)-[:HAS]->(:属性 id: 11, label: 'shape', value: 'round'), (f)-[:HAS]->(:Attribute id: 20, label: 'color', value: 'red' ), (f)-[:HAS]->(:Attribute id: 21, label: 'shape', value: 'round') 然后我的问题是查询“颜色”为“蓝色”的实体例如,“形状”是“圆形”。 我会接受你的回答,虽然它不能完全回答我的问题,因为它有很大的帮助!再次,谢谢。您能否更新您的答案以匹配我的问题?【参考方案2】:

所以我最终创建了以下属性:

:params props: [["name", "Athanase"], ["age", 22], ["color", "blue"]]

然后我将查询更新为:

MATCH (e:Entity) WHERE ALL(p IN $props WHERE SIZE ([(e)-[:HAS]->(a:Attrib) WHERE (a.label = p[0] AND a.value = p[1]) | 1]) > 0) RETURN e;

看起来它工作正常。

【讨论】:

问题是我仍然不太理解@cybersam 提出的答案。任何解释将不胜感激。 这个答案要求你的节点有一对尴尬的 labelvalue 属性。这不是必需的,也不是最佳实践。我的回答显示了如何避免这种情况并允许您使用任意属性名称。 在“属性”节点上设置“标签”和“值”属性不是一种选择。该模型是为非常特定的目的而设计的,出于保密原因,我不会在这里详细说明。最佳实践只有那么好,多年来我已经学会了如何始终质疑它们。话虽如此,我从您的回答中获得了一些有用的知识,我真的很感激。

以上是关于Cypher - 通过其连接节点的属性匹配节点?的主要内容,如果未能解决你的问题,请参考以下文章

如何优化Neo4J Cypher查询?

neo4j cypher 节点可以模糊匹配么

neo4j cypher - 匹配不存在相同类型的另一个特定节点的节点

如何使用Cypher返回节点的所有属性?

Cypher where子句因多条路径而失败

Cypher语法