在不同的属性上使用neo4j DISTINCT和ORDER BY

时间:2012-12-24 22:41:53

标签: neo4j graph-databases cypher

我正在尝试在neo4j版本1.9M02上运行以下cypher查询

START me=node(2)
            MATCH me-[:FOLLOWS]->friends
            ,friends-[fr:ADDED|STOCKS]->products
            ,me-[r?]->products
            WHERE r is null
            RETURN products._id
            ORDER BY fr.CreatedOn DESC
            SKIP 0
            LIMIT 10

根据关系创建时间排序,我希望得到我朋友们添加或存储的所有产品,这些产品都不是由我添加或存储的。此查询返回正确的结果,但具有重复的products._id值(一个用户添加产品,其他用户使用STOCKED)。但我只需要这个产品的一个实例._id所以我试过

START me=node(2)
            MATCH me-[:FOLLOWS]->friends
            ,friends-[fr:ADDED|STOCKS]->products
            ,me-[r?]->products
            WHERE r is null
            RETURN DISTINCT products._id
            ORDER BY fr.CreatedOn DESC
            SKIP 0
            LIMIT 10

(为products._id添加了DISTINCT)但这次我遇到了 Unknown identifier fr 错误。所以我把fr添加到RETURN语句

START me=node(2)
            MATCH me-[:FOLLOWS]->friends
            ,friends-[fr:ADDED|STOCKS]->products
            ,me-[r?]->products
            WHERE r is null
            RETURN DISTINCT products._id,fr
            ORDER BY fr.CreatedOn DESC
            SKIP 0
            LIMIT 10

此查询可以正常运行,但会像以前一样返回重复的产品ID。

过去几天我一直只玩neo4j,所以根本不是专家。如果有人能帮助我,我真的很感激。

2 个答案:

答案 0 :(得分:9)

我使用console.neo4j.org

创建了little case

通过以下查询,我回来[4, 3, 2, 4, 3, 2, 4, 3 ,2]

START me=node(1) 
MATCH me-[:FOLLOWS]->friends
,friends-[fr:ADDED|STOCKS]->products
,me-[r?]->products 
WHERE r is null 
with distinct products._id as id, fr.CreatedOn as CreatedOn 
ORDER BY CreatedOn DESC 
RETURN id

在最后一行加上不同的内容,然后我回来[3, 4, 2]

START me=node(1) 
MATCH me-[:FOLLOWS]->friends
,friends-[fr:ADDED|STOCKS]->products
,me-[r?]->products 
WHERE r is null 
with distinct products._id as id, fr.CreatedOn as CreatedOn 
ORDER BY CreatedOn DESC 
RETURN distinct id

看起来订单会因为不同而丢失。

修改

在对此提交an issue on github之后,在我获得answer之前很长一段时间。

答案中的建议是运行此查询:

START me=node(1) 
MATCH me-[:FOLLOWS]->friends-[fr:ADDED|STOCKS]->product, 
WHERE not(me-->product)
RETURN product._id as id, min(fr.CreatedOn) as CreatedOn 
ORDER BY CreatedOn DESC 

我修改了查询,只返回id:

START me=node(1) 
MATCH me-[:FOLLOWS]->friends-[fr:ADDED|STOCKS]->product 
WHERE not(me-->product) 
WITH product._id as id, min(fr.CreatedOn) as CreatedOn 
ORDER BY CreatedOn DESC 
RETURN id

瞧,它返回[4, 3, 2]! (我还创建了一个updated test case。)

答案 1 :(得分:0)

通过使用聚合函数MIN,您可以提取最早的CreatedOn日期。完成后,可以在最早的日期对结果集进行简单的排序,如下所示:

START me=node(1) 
MATCH me-[:FOLLOWS]->friends-[fr:ADDED|STOCKS]->product, 
WHERE not(me-->product)
RETURN product._id as id, min(fr.CreatedOn) as CreatedOn 
ORDER BY CreatedOn DESC 

H个,

安德烈斯