1

我正在使用 Neo4j 为我的组织进行概念验证。例如,我选择对公司管理层次结构(谁管理谁,谁由 X 管理等)进行建模。看起来它在图表中效果很好,但我找不到任何方法以我想要显示的方式从 Neo4j 中取回数据。

我需要的查询是:告诉我向 X 汇报的每个人,一直向下。这意味着,每个直接向 X 报告的人以及向他们报告的任何人等。

我看到我可以在 Cypher 中做到这一点,但它会返回一个扁平的 2d 结果。但这不是很有帮助,因为它没有描述结果的管理结构。

看来我真正想要的是一个人的图表。这可以在不对每个管理级别进行查询的情况下完成吗?

我正在使用 C# Neo4JClient,但此时我对任何解决方案都感兴趣。

4

2 回答 2

3

您可以将所有路径返回到X结构的根目录。

start x=node:people(name='foo')
match path = x<-[:REPORTS_TO*]-person
return path

您还可以在路径集合上返回nodes(path)rels(path)使用任何表达式filter,或谓词, length, 。extractALLANYSINGLENONE

于 2012-09-17T23:44:13.710 回答
0

这是我提取树的解决方案:

注意:此解决方案适用于我的项目,但我必须针对您的问题对其进行更改,因为我们还有一些其他不必要的限制。

找到所有要提取的根实体后,

With entity as rootEntity

我已将这些匹配项添加到查询中:

match
    rootEntity-[*0..]->subEntity, 
    parentEntity-->subEntity

这在哪里:

where rootEntity = subEntity or (rootEntity-[*0..]->parentEntity)

然后,我返回(不同)数据如下:

id(rootEntity), 
id(parentEntity),
id(entity),
subEntity

其余的解决方案是 C#:

首先需要一些数据修复,因为 NEO4J 将多次返回根实体(每个传入关系一个):

results.ForEach(
        x =>
        {
            if (x.Id == x.RootId)
                x.ParentId = 0;
        });

并按 ID 区分:

results =
    results
    .GroupBy(x => x.Id)
    .Select(x => x.First())
    .ToList();

然后,我们可以构建树:

    ....
    var trees = results
        .GroupBy(x => x.RootId)
        .Select(singleTreeEntities => GenerateSingleEntity(singleTreeEntities.Key, singleTreeEntities))

    return trees;
}

private Entity GenerateSingleEntity(long id, IEnumerable<Entities> treeEntities)
{
    var currEntity = treeEntities.SingleOrDefault(x => x.Id == id);

    return new Entity
    {
        Id = id,
        SomeData = currEntity.SubEntity.SomeData,
        SomeOtherData = currEntity.SubEntity.SomeOtherData,
        ChildEntities =
            treeEntities
                .Where(x => x.ParentId == id)
                .Select(x => GenerateSingleEntity(x.Id, treeEntities)))
    };
}
于 2013-05-26T11:27:03.910 回答