Match Cypher中的多个关系

时间:2014-04-24 22:58:56

标签: neo4j cypher

尝试根据标签查找类似的电影。但是我还需要给定电影及其每个类似电影的所有标签(进行一些计算)。但令人惊讶的是collect(h.w)给出了h.w的重复值(其中wh的属性)

这是密码查询。请帮忙。

MATCH (m:Movie{id:1})-[h1:Has]->(t:Tag)<-[h2:Has]-(sm:Movie),
(m)-[h:Has]->(t0:Tag), 
(sm)-[H:Has]->(t1:Tag) 
WHERE m <> sm 
RETURN distinct(sm), collect(h.w)

基本上是像

这样的查询
MATCH (x)-[h]->(y), (a)-[H]->(b) 
RETURN h

返回h n times的每个结果,其中nresults for H的数量。有什么方法吗?

2 个答案:

答案 0 :(得分:1)

我复制了这个问题的数据模型以帮助回答它。

Example data model

然后我使用Neo4j的在线控制台设置了一个示例数据集:http://console.neo4j.org/?id=dakmi3

从您的问题中运行以下查询:

MATCH (m:Movie { title: "The Matrix" })-[h1:HAS_TAG]->(t:Tag),
      (t)<-[h2:HAS_TAG]-(sm:Movie),
      (m)-[h:HAS_TAG]->(t0:Tag),
      (sm)-[H:HAS_TAG]->(t1:Tag)
WHERE m <> sm
RETURN DISTINCT sm, collect(h.weight)

结果是:

(1:电影{title:&#34; The Matrix:Reloaded&#34;})[0.31,0.12,0.31,0.12,0.31,0.01,0.31,0.01]

问题是返回了重复的关系,这会导致集合中出现重复的重量。解决方案是使用WITH来限制与不同记录的关系,然后返回这些关系的权重集合。

MATCH (m:Movie { title: "The Matrix" })-[h1:HAS_TAG]->(t:Tag),
      (t)<-[h2:HAS_TAG]-(sm:Movie),
      (m)-[h:HAS_TAG]->(t0:Tag),
      (sm)-[H:HAS_TAG]->(t1:Tag)
WHERE m <> sm
WITH DISTINCT sm, h
RETURN sm, collect(h.weight)

(1:电影{title:&#34; The Matrix:Reloaded&#34;})[0.31,0.12,0.01]

答案 1 :(得分:0)

我担心我还没有完全明白你的意图,但关于重复结果的一般问题,这就是断开模式的工作方式。 Cypher必须考虑像

这样的东西
(:A), (:B)

作为一个模式,而不是两个。这意味着任何令人满意的图形结构都被认为是一种独特的匹配。假设您有来自

的图表
CREATE (:A), (:B), (:B)

并查询上面的模式,得到两个结果,即

neo4j-sh (?)$ MATCH (a:A),(b:B) RETURN *;
==> +-------------------------------+
==> | a             | b             |
==> +-------------------------------+
==> | Node[15204]{} | Node[15207]{} |
==> | Node[15204]{} | Node[15208]{} |
==> +-------------------------------+
==> 2 rows
==> 53 ms

类似地,当匹配您的模式时,(x)-[h]->(y), (a)-[H]->(b) cypher会考虑两个模式部分的每个组合,以构成一个完整模式的唯一匹配 - 因此h的结果会被H的结果复合{1}}。

这是模式匹配的工作方式。要实现您想要的功能,您可以首先考虑是否确实需要查询断开连接的模式。如果这样做,或者连接模式也生成冗余匹配,则聚合一个或多个模式部分。一个简单的案例可能是

CREATE (a:A), (b1:B), (b2:B)
    , (c1:C), (c2:C), (c3:C)
    , a-[:X]->b1, a-[:X]->b2
    , a-[:Y]->c1, a-[:Y]->c2, a-[:Y]->c3

查询

MATCH (b:B)<-[:X]-(a:A)-[:Y]->(c:C)              // with 1 (a), 2 (b) and 3 (c) you get 6 matched paths
RETURN a, collect (b) as bb, collect (c) as cc   // after aggregation by (a) there is one path

有时将聚合作为中间步骤

是有意义的
MATCH (b)<-[:X]-(a:A)              // 2 paths
WITH a, collect(b) as bb           // 1 path
MATCH a-[:Y]->(c)                  // 3 paths
RETURN a, bb, collect(c) as cc     // 1 path