Neo4j cypher查询收集在收集中

时间:2014-12-30 10:17:48

标签: neo4j match cypher

我有一个问题:

start brand=node(62) match  brand-[:CREATED_A]->(campaign:Campaign)<-->(node) 
return DISTINCT  brand,campaign,collect(node) ;

现在结果几乎像我想的那样回来了。我缺少的一件事是我希望拥有以下层次结构:

品牌有很多广告系列和广告系列都有很多节点连接到它,所以广告系列中的节点类型。

现在,广告系列会多次返回到每个返回的广告系列。

2 个答案:

答案 0 :(得分:6)

我提供了一个Neo4j Gist来说明解决方案。简而言之,它使用文字地图来格式化数据,并使用两个收集来确保品牌不会多次出现。

MATCH 
    (brand:Brand)-[:CREATED_A]->(campaign:Campaign)<-->(node)
WITH 
    brand, 
    { 
        campaign : campaign, 
        nodes : COLLECT(node)
    } AS campaigns
WITH 
    { 
        brand : brand, 
        campaigns : COLLECT(campaigns)
    } AS brands
RETURN brands

这使得品牌出现一次,您的输出格式就会很好。

答案 1 :(得分:2)

Cypher是一种非常强大的语言。如果您知道要从节点获取哪些属性,您甚至可以返回类似json的输出,该输出也维护您在图形中实际建模的结构,您可以执行以下操作:

MATCH (brand:Brand)-[:CREATED_A]->(campaign:Campaign)<-->(node)
WITH 
    brand, 
    campaign as campaign,
    COLLECT({
         property1 : node.property1,
         property2 : node.property2
    }) as nodes
RETURN 
    { 
        name : brand.name,
        logoUrl : brand.logoUrl,
        campaigns : COLLECT({
            name : campaign.name,
            timestamp : campaign.timestamp,
            nodes : nodes
        })
    } as brands

这将输出一个json结构,例如:

[
    {
        name : "my name",
        logoUrl : "http://www...",
        campaigns : [
            {
                name : "my campaign name",
                timestamp : 1484172044462,
                nodes : [
                    {
                        property1 : "property1",
                        property2 : "property2"
                    }
                ]
             }
         ]
    }
]

这实际上很好地反映了您的图表模型。

此外,由于您没有进行RETURN COLLECT(...),因此您可以迭代Record结果而不是获取第一个(也是唯一一个)记录并将所有行放入其中。当您处于嵌入式服务器的情况下,这可能是一种方便的方式,您可以在其中实际流式传输结果数据,而不是一次性检索它。

即使您没有任何馆藏(例如,一个广告系列只有一个节点),并且路径越来越深,这种方法也能很好地运作。 但是,当您的模型是树(或更糟的是图表)时,您可能会遇到挑战。

你可以在这个好主意中找到更多细节: https://gist.github.com/rherschke/9269173