1

私は Neo4jClient と Neo4J を初めて使用するので、データをクエリして、neo4j のデータのようなマスター詳細を取得する方法がわかりませんでした。これを例で説明しましょう。

以下のようなグラフがあるとします。

root -[:DEFINES] -> Shipment 1 
                -[:HAS_CONSIGNMENT]->Consignment 1
                            -[:HAS_ITEM]->Load Item 11
                            -[:HAS_ITEM]->Load Item 12
                            -[:HAS_CONSIGNEE]->Consignee 1
                -[:HAS_CONSIGNMENT]->Consignment 2
                            -[:HAS_ITEM]->Load Item 21
                            -[:HAS_ITEM]->Load Item 22
                            -[:HAS_CONSIGNEE]->Consignee 2

ここで、すべてのグラフを取得して、以下のようにドメイン モデルに入力したいとします。

public class Shipment
{
    public List<Consignment> Consignments {get; set;}
}

 public class Consignment
 {
     public List<LoadItem> LoadItems {get; set;}
     public Consignee ShippedTo {get; set;}
 }

 public class LoadItem
 {
 }

私はおそらく以下のようなCypherクエリを構築できることを知っています。neo4jclientを使用して接続グラフを取得する方法

query = client.Cypher.Start(new { root = client.RootNode }).
            Match("root-[:DEFINES]->load-[:HAS_CONSIGNMENT]->consignments -[:HAS_ITEM]->loadItem").Match("consignments-[:HAS_CONSIGNEE]->consignee").
            Where((Load load) => load.Id == myId).
            Return(
            (load,consignments, loaditems)=>
            new {
                loadInfo = load.As<Node<Load>>(),
                consignments = consignments.CollectAs<Consignment>(),
                loadItems = loaditems.CollectAs<LoadItem>()
            }); 

しかし、これを第 2 レベルのリストに変換して、委託 2 に積荷品目 21 と 22 があり、委託 1 に品目 11 と 12 があることを示す方法がわかりません。

私は主にEFで作業しており、グラフクエリは私にとって本当に新しいものであるため、これがどのように機能するかを理解するのを手伝ってください。

よろしくキラン

4

1 に答える 1

0

そうです、これが私がこれを機能させる方法です(Tathamがより良い答えを出すと確信しています-少し待ってください)

public static ICollection<Shipment> Get()
{
    var query = GraphClient.Cypher
        .Start(new {root = GraphClient.RootNode})
        .Match(
            string.Format("root-[:{0}]->shipment-[:{1}]-consignments-[:{2}]->loadItem", Defines.TypeKey, HasConsignment.TypeKey, HasItem.TypeKey),
            string.Format("consignments-[:{0}]->consignee", HasConsignee.TypeKey)
        )
        .Return((shipment, consignments, loadItem, consignee) =>
        new
        {
            Shipment = shipment.As<Node<Shipment>>(),
            Consignment = consignments.As<Consignment>(),
            LoadItem = loadItem.CollectAs<LoadItem>(),
            Consignee = consignee.As<Consignee>(),
        });

    var results = query.Results.ToList();
    var output = new List<Node<Shipment>>();

    foreach (var result in results)
    {
        var shipmentOut = output.SingleOrDefault(s => s.Reference == result.Shipment.Reference);
        if (shipmentOut == null)
        {
            shipmentOut = result.Shipment;
            shipmentOut.Data.Consignments = new List<Consignment>();
            output.Add(shipmentOut);
        }

        result.Consignment.LoadItems = new List<LoadItem>();
        result.Consignment.LoadItems.AddRange(result.LoadItem.Select(l => l.Data));
        shipmentOut.Data.Consignments.Add(result.Consignment);
    }

    return output.Select(s => s.Data).ToList();
}

これにより、すべての貨物や貨物などを取得できます。 ただし、そうであることに注意してください.Where((Load load) => load.Id == myId)

結果として、'root' を使用する必要がなく、Shipment ID を渡すことができるため、コードを少し単純化できます。

public static Shipment Get2(NodeReference<Shipment> shipmentNodeReference)
{
    var query = GraphClient.Cypher
        .Start(new {shipment = shipmentNodeReference})
        .Match(
            string.Format("shipment-[:{0}]-consignments-[:{1}]->loadItem", HasConsignment.TypeKey, HasItem.TypeKey), 
            string.Format("consignments-[:{0}]->consignee", HasConsignee.TypeKey)
        )
        .Return((shipment, consignments, loadItem, consignee) =>
        new {
            Shipment = shipment.As<Node<Shipment>>(),
            Consignment = consignments.As<Consignment>(),
            LoadItem = loadItem.CollectAs<LoadItem>(),
            Consignee = consignee.As<Consignee>(),
        });

    var results = query.Results.ToList();

    //Assuming there is only one Shipment returned for a given ID, we can just take the first Shipment.
    Shipment shipmentOut = results.First().Shipment.Data;
    shipmentOut.Consignments = new List<Consignment>();
    foreach (var result in results)
    {
        result.Consignment.ShippedTo = result.Consignee;
        result.Consignment.LoadItems = new List<LoadItem>();
        result.Consignment.LoadItems.AddRange(result.LoadItem.Select(l => l.Data));
        shipmentOut.Consignments.Add(result.Consignment);
    }

    return shipmentOut;
}

参考までに、私が使用していた DataElements は次のとおりです。

public class Shipment
{
    public string Id { get; set; }
    public List<Consignment> Consignments { get; set; }
    public override string ToString() { return Id; }
}

public class Consignment
{
    public string Id { get; set; }
    public List<LoadItem> LoadItems { get; set; }
    public Consignee ShippedTo { get; set; }
    public override string ToString() { return Id; }
}

public class Consignee
{
    public string Name { get; set; }
    public override string ToString() { return Name; }
}

public class LoadItem
{
    public string Item { get; set; }
    public override string ToString() { return Item; }
}

リレーションシップはすべて次のように定義されます。

public class HasConsignment : Relationship, IRelationshipAllowingSourceNode<Shipment>, IRelationshipAllowingTargetNode<Consignment>
{
    public const string TypeKey = "HAS_CONSIGNMENT";

    public HasConsignment() : base(-1) {}
    public HasConsignment(NodeReference targetNode): base(targetNode) {}
    public HasConsignment(NodeReference targetNode, object data) : base(targetNode, data) {}

    public override string RelationshipTypeKey { get { return TypeKey; } }
}

(必要に応じて明らかな変更を加えます)

于 2013-08-12T14:39:22.510 に答える