问题描述
我当前正在尝试展开要使用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
节点标识符。