我正在使用Neo4j为我的组织制作一个概念验证。作为一个例子,我选择模拟公司管理层次结构(谁管理谁,谁由X管理等)。看起来它在图表中运行良好,但我找不到任何方法以我想要显示的方式将数据从Neo4j中恢复出来。
我需要的查询是:告诉我每个人向人X报告,一直向下。这意味着,每个直接向X报告的人以及向他们报告的任何人等。
我看到我可以在Cypher中做到这一点,但它会返回一个扁平的2d结果。但这并不是很有用,因为它没有描述结果的管理结构。
看起来我真正想要的是人们一路下来的图表。这可以在不对每个级别的管理进行查询的情况下完成吗?
我正在使用C#Neo4JClient,但我现在对任何解决方案感兴趣。
答案 0 :(得分:3)
您可以返回结构的根X
的所有路径。
start x=node:people(name='foo')
match path = x<-[:REPORTS_TO*]-person
return path
您还可以返回nodes(path)
或rels(path)
或使用任何表达式filter
,length
,extract
或谓词ALL
,路径集合上的ANY
,SINGLE
,NONE
。
答案 1 :(得分: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)))
};
}