[Neo4j][Cypher Query] 过滤节点或关系节点属性,然后返回所有节点及其关系节点

问题描述 投票:0回答:1

我有一个 Neo4j DB,其中包含

Resource
节点以及多个关系节点,包括
Tag
Address
PhoneNumber
等。

Resource
的架构如下:

Resource: {
  name: str,
  description: str,
  legal_name: str,
  organization_type: str,
}

Tag
的架构如下:

Resource: {
  tag: str,
}

我正在构建一个查询,返回所有

Resource
节点及其关系节点,其中
Resource
节点具有包含特定字符串的属性,并且/或相关
Tag
节点具有属性包含相同的字符串。

返回示例案例:

  1. A
    Resource
    节点确实具有一个或多个包含字符串“school”的属性,但所有相关
    Tag
    节点不具有包含字符串“school”的
    tag
    属性:
    Resource
    节点与它的所有关系节点
  2. A
    Resource
    节点不具有任何包含字符串“school”的属性,但至少有一个相关
    Tag
    节点具有包含字符串“school”的
    tag
    属性:返回
    Resource
    节点以及它的所有关系节点
  3. Resource
    节点确实具有一个或多个包含字符串“school”的属性,并且至少有一个相关
    Tag
    节点确实具有包含字符串“school”的
    tag
    属性:
    Resource
    节点是连同其所有关系节点一起返回

我目前正在使用以下查询,它在大多数情况下都有效;但是,对于上述情况 2,结果集中不会返回原始

Resource
节点的其他关系节点。理想情况下,我们总是会获得符合上述条件的
Resource
节点的所有关系节点。任何帮助将不胜感激!

MATCH (n:Resource)-[]->(m) 
WHERE n.name CONTAINS 'school'
    OR n.description CONTAINS 'school'
    OR n.legal_name CONTAINS 'school'
    OR n.organization_type CONTAINS 'school'
    OR m.tag CONTAINS 'school'
RETURN n, collect(m);
neo4j cypher
1个回答
0
投票

您可以尝试这样的查询:

MATCH (n:Resource)
WHERE EXISTS {
    MATCH (n)-[*0..1]->(x)
    WHERE (x:Resource OR x:Tag)
    AND any(prop IN ['name', 'description', 'legal_name', 'organization_type', 'tag'] WHERE x[prop] CONTAINS 'school')
}

WITH n, [(n)-[]->(m) | m] as resources
RETURN n, resources;

这使用 EXISTS {} 子查询来表示您正在寻找一个节点(可以是同一节点,也可以是连接的节点),该节点是具有任何给定属性的 :Resource 或 :Tag 节点属性值包含“学校”。

对于通过该过滤器的结果节点,然后您可以匹配并收集连接的节点(尽管在本例中我使用模式理解来执行此操作,这会更有效)。

编辑:修复了 AND 和 OR 运算符的分组,这应确保必须始终考虑 any() 列表谓词。

© www.soinside.com 2019 - 2024. All rights reserved.