在Neo4J Client for C#中解开结果并与动态标签合并

问题描述

我当前正在尝试展开要使用Neo4J Client合并到数据库的对象列表。我想做的是展开列表,并使用基于项目本身属性生成标签创建节点,而不是对标签名称进行硬编码。根据我的发现,我必须使用APOC合并方法。但是,我无法将其转换为Neo4J客户端。在neo4J解释中,它们在apoc.merge.node调用之后产生一个节点,然后返回该节点。但是,我不能简单地返回该节点,也不能设置该节点(我已经搞砸了,有一点我可以使用标签,但是它用列表中的最后一项覆盖了所有属性)。 / p>

我似乎错过了一些基本知识,但我不太确定该怎么做。这里是否有人知道如何使用neo4J客户端执行此操作(如果可能,请给出一些解释说明发生了什么情况)?我对开发世界还很陌生,我觉得我在这方面缺少一个至关重要的了解。

我尝试过的代码将所有属性转换为最后一个节点的属性,但至少按照我的期望创建了标签

        public async void CreateBatchItems(List<TToDataBase> itemList)
        {
            await Client.Cypher
            .Unwind(itemList,"row")
            .Merge("(n)")
            .With("row,n")
            .Call("apoc.merge.node([n.Name],n)").Yield("node")
            .Set("n += node")
            .ExecuteWithoutResultsAsync();
        }

提前谢谢!

编辑:

关于输入的一些说明: 这些对象实际上是非常基本的,因为(至少到目前为止),它们仅包含一个名称一个objectID(这些对象ID稍后用于创建关系)。因此,它是一个非常基本的类,具有两个属性

 public class Neo4jbaseClass
    {
        public Neo4jbaseClass() { }

        public Neo4jbaseClass(string name,string objectId)
        {
            Name = name;
            ObjectId = objectId;
        }

        [JsonProperty(PropertyName = "ObjectId")]
        public string ObjectId { get; set; }

        [JsonProperty(PropertyName = "Name")]
        public string Name { get; set; }
    }

我还尝试了一些细微的变化,其中此类也具有添加属性

        [JsonProperty(PropertyName = "PropertyMap")]
        public IProperty PropertyMap { get; set; }  

其中PropertyMap是另一个具有名称和objectId的基本对象。无论如何,这似乎是一个将来打样的好主意,因此可以轻松扩展属性列表,而无需更改基础对象。

解决方法

[编辑]

主要问题是Merge("(n)")与任何已存在的任意节点匹配。

您尚未显示itemList的每个元素的数据结构,因此此答案将假定它看起来像这样:

{Name: 'SomeLabel',id: 123,Props: {foo: 'xyz',bar: true}}

使用上述数据结构,这应该可以工作:

public async void CreateBatchItems(List<TToDataBase> itemList)
{
    await Client.Cypher
      .Unwind(itemList,"row")
      .Call("apoc.merge.node([row.ObjectId],row.id)").Yield("node")
      .Set("node += row.Props")
      .ExecuteWithoutResultsAsync();
}

[更新]

您添加到问题中的数据结构与我的想象完全不同。由于row中的两个属性都不是映射,因此.Set("node += row.Props")会产生错误。

使用每一行的数据结构,这可能会起作用:

public async void CreateBatchItems(List<TToDataBase> itemList)
{
    await Client.Cypher
      .Unwind(itemList,"row")
      .Merge("(n:Foo {id: row.ObjectId})")
      .Set("n += row.Name")
      .ExecuteWithoutResultsAsync();
}

此代码将节点标签Foo分配给所有生成的节点。节点应始终具有标签,这样可以提高清晰度,也可以提高效率-特别是如果您还创建indexes。例如,:Foo(id)上的索引将使上面的查询更加有效。

此代码还假定id属性应该包含唯一的Foo节点标识符。