Neo4j:如何从不同的起始节点返回多个路径

时间:2015-11-12 21:51:01

标签: c# neo4j cypher neo4jclient

我有类似的问题 this question但我使用的是带有neo4jClient的c#而不是Java。

我可以使用以下代码获取给定节点的父路径,但在尝试查找许多节点的父路径时,它会成为性能瓶颈。 我想要的是一种使用节点键列表调用图形数据库并返回父路径列表的方法。这样我就可以返回结果字典而不是单个列表。

任何帮助实现这一点将不胜感激!此外,如果我的原始密码查询可以改进,我也会对此持开放态度。

    public IEnumerable<IGenericEntity> GetPath(string entityCompositeKey, GraphRelationship relationship)
    {
        var entity = new GenericEntity();
        entity.setCompositeKey(entityCompositeKey);
        var pathToRoot = new List<GenericEntity>(){ entity };

        var query = new CypherFluentQuery(graphClient)
                    .Match("p = (current)-[r:" + relationship.Name + "*0..]->()")
                    .Where((IGenericEntity current) => current.CompositeKey == entityCompositeKey)
                    .Return(() => Return.As<IEnumerable<GenericEntity>>("nodes(p)"))
                    .OrderByDescending("length(p)")
                    .Limit(10);

        var queryText = query.Query.QueryText;
        var paramText = query.Query.QueryParameters;
        if (query.Results != null)
        {
            var graphResults = query.Results.FirstOrDefault();
            if (graphResults != null && graphResults.ToList().Count > 0)
            {
                pathToRoot = graphResults.ToList();
            }
        }
        return pathToRoot;
    }

1 个答案:

答案 0 :(得分:0)

有一些我不确定的事情 - 而且很可能是我的测试数据库的设置方式。

要回答关于如何传入多个起始节点的初始问题 - 最好使用UNWIND运算符进行处理,Neo4jClient运算符如下所示:

var enumerable = new string[] { "a", "b" }
client.Unwind(enumerable, "item"). /*The rest*/

Obvs,如果你把它放在当前查询的顶部,你会得到一个 monster 节点集,你不会知道哪个Root实体引用哪个, soo ......让我们做一些预测...

要进行投射,我们必须有一些东西投射到:

public class Result {
    public GenericEntity Root { get; set; }
    public List<GenericEntity> Nodes { get; set; }
    public int Length { get; set; }
}

这将包含Root节点及其路径,现在填充。

public IEnumerable<Result> GetPath(IEnumerable<string> rootKeys, GraphRelationship relationship)
{
    var query = new CypherFluentQuery(Client)
                .Unwind(rootKeys, "entityRootKey")
                .Match(string.Format("p = (root)-[r:{0}*0..]->()", relationship.Name))
                .Where("root.CompositeKey = entityRootKey")
                .With("{Root:root, Nodes: nodes(p), Length: length(p)} as res")
                .Return((res) => res.As<Result>())
                .OrderByDescending("res.Length")
                .Limit(10);

    var results = query.Results;
    return results;
}

我没有使用.Where创建Func<T>参数,这是因为参数是在.Unwind语句中创建的。

明智的用法 - 像这样:

var res = GetPath(new[] {"a", "b"}, new GraphRelationship {Name = "RELATED"});
foreach (var result in res)
{
    Console.WriteLine($"{result.Root.CompositeKey} => {result.Length}");
    foreach (var node in result.Nodes)
        Console.WriteLine($"\t{node.CompositeKey}");
}