gpt4 book ai didi

c# - 如何在 Neo4j v2 中使用 Neo4jClient 创建节点?

转载 作者:太空狗 更新时间:2023-10-29 17:34:11 27 4
gpt4 key购买 nike

在 Neo4j v1.9.x 下,我使用了以下代码。

private Category CreateNodeCategory(Category cat)
{
var node = client.Create(cat,
new IRelationshipAllowingParticipantNode<Category>[0],
new[]
{
new IndexEntry(NeoConst.IDX_Category)
{
{ NeoConst.PRP_Name, cat.Name },
{ NeoConst.PRP_Guid, cat.Nguid.ToString() }
}
});
cat.Nid = node.Id;
client.Update<Category>(node, cat);
return cat;
}

原因是节点 ID 是自动生成的,我可以稍后使用它进行快速查找、其他查询中的起始位等。如下所示:

    private Node<Category> CategoryGet(long nodeId)
{
return client.Get<Category>((NodeReference<Category>)nodeId);
}

这使得以下看起来运行良好。

    public Category CategoryAdd(Category cat)
{
cat = CategoryFind(cat);
if (cat.Nid != 0) { return cat; }
return CreateNodeCategory(cat);
}

public Category CategoryFind(Category cat)
{
if (cat.Nid != 0) { return cat; }
var node = client.Cypher.Start(new {
n = Node.ByIndexLookup(NeoConst.IDX_Category, NeoConst.PRP_Name, cat.Name)})
.Return<Node<Category>>("n")
.Results.FirstOrDefault();
if (node != null) { cat = node.Data; }
return cat;
}

现在 cypher Wiki、示例和坏习惯建议在所有 CRUD 中使用 .ExecuteWithoutResults()。

所以我的问题是您如何获得节点 ID 的自动增量值?

最佳答案

首先,对于 Neo4j 2 及更高版本,您始终需要从引用框架“我将如何在 Cypher 中执行此操作?”开始。然后,也只有那时,您才担心 C#。

现在,提炼您的问题,听起来您的主要目标是创建一个节点,然后返回对它的引用以供进一步工作。

你可以用密码来做到这一点:

CREATE (myNode)
RETURN myNode

在 C# 中,这将是:

var categoryNode = graphClient.Cypher
.Create("(category {cat})")
.WithParams(new { cat })
.Return(cat => cat.Node<Category>())
.Results
.Single();

但是,这仍然不是您在原始 CreateNodeCategory 中所做的 100%方法。您正在数据库中创建节点,为其获取 Neo4j 的内部标识符,然后将该标识符保存回同一节点。基本上,您正在使用 Neo4j 为您生成自动递增的数字。这是功能性的,但不是真正的好方法。我会解释更多...

首先,Neo4j 甚至还给您节点 ID 的概念正在消失。它是一个内部 标识符,实际上恰好是磁盘上的文件偏移量。它可以改变。这是低水平的。如果您稍微考虑一下 SQL,您是否使用 SQL 查询来获取行的文件字节偏移量,然后引用它以供将来更新?答:没有;您编写一个查询,一次性查找和操作该行。

现在,我注意到您已经有了一个 Nguid节点上的属性。你为什么不能用它作为id?或者,如果名称始终是唯一的,则使用该名称? (与域相关的 ID 总是比魔数(Magic Number)更可取。)如果两者都不合适,您可能需要查看像 SnowMaker 这样的项目。来帮助你。

接下来,我们需要看看索引。您正在使用的索引类型在 2.0 文档中称为 "Legacy Indexing"并错过了一些很酷的 Neo4j 2.0 功能。

对于这个答案的其余部分,我将假设您的 Category类看起来像这样:

public class Category
{
public Guid UniqueId { get; set; }
public string Name { get; set; }
}

让我们开始使用 label 创建类别节点:

var category = new Category { UnqiueId = Guid.NewGuid(), Name = "Spanners" };
graphClient.Cypher
.Create("(category:Category {category})")
.WithParams(new { category })
.ExecuteWithoutResults();

并且,作为一次性操作,让我们建立一个 schema-based indexName 上具有 Category 的任何节点的属性标签:

graphClient.Cypher
.Create("INDEX ON :Category(Name)")
.ExecuteWithoutResults();

现在,我们无需担心手动使索引保持最新。

我们还可以引入索引和unique constraintUniqueId :

graphClient.Cypher
.Create("CONSTRAINT ON (category:Category) ASSERT category.UniqueId IS UNIQUE")
.ExecuteWithoutResults();

现在查询非常简单:

graphClient.Cypher
.Match("(c:Category)")
.Where((Category c) => c.UniqueId == someGuidVariable)
.Return(c => c.As<Category>())
.Results
.Single();

与其查找类别节点,然后再进行另一个查询,不如一次性完成:

var productsInCategory = graphClient.Cypher
.Match("(c:Category)<-[:IN_CATEGORY]-(p:Product)")
.Where((Category c) => c.UniqueId == someGuidVariable)
.Return(p => p.As<Product>())
.Results;

如果你想更新一个类别,也可以一次性完成:

graphClient.Cypher
.Match("(c:Category)")
.Where((Category c) => c.UniqueId == someGuidVariable)
.Update("c = {category}")
.WithParams(new { category })
.ExecuteWithoutResults();

最后,你的 CategoryAdd当前方法 1) 执行一次数据库命中以查找现有节点,2) 第二次数据库命中以创建新节点,3) 第三次数据库命中以更新其上的 ID。相反,您也可以使用 MERGE keyword 将所有这些压缩到单个调用中:

public Category GetOrCreateCategoryByName(string name)
{
return graphClient.Cypher
.WithParams(new {
name,
newIdIfRequired = Guid.NewGuid()
})
.Merge("(c:Category { Name = {name})")
.OnCreate("c")
.Set("c.UniqueId = {newIdIfRequired}")
.Return(c => c.As<Category>())
.Results
.Single();
}

基本上,

  1. 不要使用 Neo4j 的内部 ID 作为破解管理您自己身份的方法。 (但他们可能会在未来发布某种形式的自动编号。即使他们这样做了,像电子邮件地址或 SKU 或机场代码或......这样的域身份是首选。你甚至并不总是需要一个 id:你通常可以推断出一个节点基于其在图中的位置。)

  2. 一般来说,Node<T>会随着时间消失。如果您现在使用它,您只是在积累遗留代码。

  3. 研究标签和基于模式的索引。它们会让您的生活更轻松。

  4. 尝试在一个查询中做事。会快很多。

希望对您有所帮助!

关于c# - 如何在 Neo4j v2 中使用 Neo4jClient 创建节点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19534511/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com