Neo4j 查询具有 2 个关系的节点集和每个关系节点的设置值

Neo4j Query set of node with 2 relationships and set value for each relationship node

提问人:Skel 提问时间:11/7/2023 最后编辑:Skel 更新时间:11/14/2023 访问量:45

问:

我有这个查询工作:

MATCH (doc:Captions)-[:HAS_CATEGORY]-(c:Categories {id: 'ne0MtinOO6DXryRvqMxS'})
MATCH (doc:Captions)-[:HAS_PILLAR]-(p:Pillars {name: 'Feel Good'})
WITH count(doc) as docCount
MATCH (doc:Captions)-[:HAS_CATEGORY]-(c:Categories {id: 'ne0MtinOO6DXryRvqMxS'})
MATCH (doc:Captions)-[:HAS_PILLAR]-(p:Pillars {name: 'Feel Good'})
WITH docCount, doc Limit 12
RETURN doc, docCount

这将返回 25 的 a 和 s,限制为 12。 但感觉就像我打了两次同样的电话。docCountdoc

我不想两次拨打相同的电话

Neo4J 密码

评论

1赞 cybersam 11/7/2023
您应该修改上述内容以清楚地说明问题。你只是发表了声明。

答:

0赞 Skel 11/7/2023 #1

在这里找到了答案

我已经更新了它,看起来像这样

MATCH (doc:Captions)
MATCH (p:Pillars {name: 'Feel Good'})
MATCH (doc)-[:HAS_PILLAR]-(p)
MATCH (c:Categories {id: 'ne0MtinOO6DXryRvqMxS'})
MATCH (doc)-[:HAS_CATEGORY]-(c)
WITH count(*) as docCount, collect(doc) as parts
UNWIND parts as a
RETURN docCount,a 
limit 12

我已根据@cyberSam的评论进行了更新

const hasPillar = pageOptionsDto.pillar
  ? `(p:Pillars {id: '${pageOptionsDto.pillar}'})<-[:HAS_PILLAR]-`
  : '';
const hasCat = pageOptionsDto.category
  ? `-[:HAS_CATEGORY]->(c:Categories {id:'${pageOptionsDto.category}'})`
  : '';
const hasOrderBy = pageOptionsDto.orderBy
  ? `ORDER BY doc.${pageOptionsDto.order}, r.date`
  : 'ORDER BY r.date';
const res = await this.neo4jService.read(`
  MATCH ${hasPillar}(doc:${collection} {active: true})${hasCat}
  WITH count(*) as docCount, collect(doc) as docs
  UNWIND docs as doc
  OPTIONAL MATCH (u:Users {id: '${activeUserData.sub}'})<-[r:USED_BY]-(doc)
  OPTIONAL MATCH (c:Categories)<-[cr:HAS_CATEGORY]-(doc)
  OPTIONAL MATCH (doc)-[:HAS_PILLAR]->(p:Pillars)
  WITH docCount, doc, r, cr, c, p
  ${hasOrderBy}
  RETURN docCount, doc, COLLECT(r) as rs, COLLECT(c) as crs, COLLECT(p) as prs
  SKIP ${pageOptionsDto.skip} LIMIT ${pageOptionsDto.limit}
`);

return res;

评论

1赞 cybersam 11/7/2023
您可能希望将所有子句替换为(关系方向是我的假设),这可能会更快。使用 PROFILE 评估查询。此外,请考虑使用索引来进一步加快速度。MATCHMATCH (:Pillars {name: 'Feel Good'})<-[:HAS_PILLAR]-(d:Captions)-[:HAS_CATEGORY]->(:Categories {id: 'ne0MtinOO6DXryRvqMxS'})
0赞 Skel 11/7/2023
啊,甜蜜的谢谢。我将研究如何使这种动态成为支柱,也可以成为类别
0赞 Vincent Rupp 11/14/2023 #2

一个简单的答案是遍历图形一次并收集节点:

MATCH (doc:Captions)-[:HAS_CATEGORY]-(:Categories {id: 'ne0MtinOO6DXryRvqMxS'})
MATCH (doc:Captions)-[:HAS_PILLAR]-(p:Pillars {name: 'Feel Good'})
with collect(doc) as Docs
with [i in range(0,12) | Docs[i] ] as MyDocs, size(Docs) as docCount
unwind MyDocs as Doc
return Doc, docCount

这将返回 12 行。每行都是一个节点和文档的计数。

您上面的评论说文档可能有一个支柱或类别。此查询将仅查找同时具有两者的文档。

为避免这种情况,请从第一个 match 语句中收集文档,从第二个 match 语句中收集文档,然后在处理之前加入列表。

另一种选择是首先在文档上匹配,然后匹配两个可能的路径。optional match