gpt4 book ai didi

neo4jclient - 如何在 neo4j .net 客户端中使用密码查询返回两个集合

转载 作者:行者123 更新时间:2023-12-02 00:10:34 24 4
gpt4 key购买 nike

我想在一个查询“tags”和“items”中返回两个集合,其中每个标签可以有 0..many 个项目。看起来如果我使用投影,它会假定一个包含两列的集合而不是两个集合,对吗?有没有更好的方法来运行此搜索查询?

我得到 “查询响应包含列标签,项目但是......匿名类型不包含接收此数据的可设置属性”

var query =  client
.Cypher
.StartWithNodeIndexLookup("tags", "tags_fulltext", keyword)
.Match("tags<-[:TaggedWith]-items")
.Return((items, tags) => new
{
Tags = tags.As<Tag>(),
Items = items.As<Item>()
});

var results = await query.ResultsAsync;

return new SearchResult
{
Items = results.Select(x => x.Items).ToList(),
Tags = results.Select(x => x.Tags).Distinct().ToList()
};

最佳答案

选项 1

场景:您想要检索与关键字匹配的所有标签,然后针对每个标签,检索每个项目(以仍然将它们链接到标签的方式)。

首先,这一行:

.StartWithNodeIndexLookup("tags", "tags_fulltext", keyword)

应该是:

.StartWithNodeIndexLookup("tag", "tags_fulltext", keyword)

也就是说,身份应该是tag而不是tags。这是因为 START 子句生成一组节点,每个节点都是一个 tag,而不是一组称为 tags 的节点。语义,但它使下一步的事情变得更简单。

现在我们将其称为 tag 而不是 tags,我们将 MATCH 子句更新为:

.Match("tag<-[:TaggedWith]-item")

意思是“对于集合中的每个标签,去找到附加到它的每个项目”。同样,'item' 是单数。

现在让我们归还它:

.Return((tag, item) => new 
{
Tag = tag.As<Tag>(),
Items = item.CollectAs<Item>()
});

在这里,我们将每个“项目”收集到一组“项目”中。我在该代码中对单数与复数的使用非常具体。

生成的 Cypher 表看起来像这样:

-------------------------
| tag | items |
-------------------------
| red | A, B, C |
| blue | B, D |
| green | E, F, G |
-------------------------

最终代码:

var query = client
.Cypher
.StartWithNodeIndexLookup("tag", "tags_fulltext", keyword)
.Match("tag<-[:TaggedWith]-item")
.Return((tag, item) => new
{
Tag = tag.As<Tag>(),
Items = item.CollectAs<Item>()
});

虽然这不是适合您的 SearchResult 的内容。

选项 2

场景:您想要检索与关键字匹配的所有标签,然后是与任何这些标签匹配的所有项目,但您不关心将两者链接在一起。

让我们回到 Cypher 查询:

START tag=node:tags_fulltext('keyword')
MATCH tag<-[:TaggedWith]-item
RETURN tag, item

这将产生一个像这样的 Cypher 结果表:

--------------------
| tag | item |
--------------------
| red | A |
| red | B |
| red | C |
| blue | B |
| blue | D |
| green | E |
| green | F |
| green | G |
--------------------

您想将这些中的每一个折叠成一个单独的、不相关的标签和项目列表。

我们可以使用 collect 来做到这一点:

START tag=node:tags_fulltext('keyword')
MATCH tag<-[:TaggedWith]-item
RETURN collect(tag) AS Tags, collect(item) AS Items

-----------------------------------------------------------------------------
| tags | items |
-----------------------------------------------------------------------------
| red, red, red, blue, blue, green, green, green | A, B, C, B, D, E, F, G |
-----------------------------------------------------------------------------

虽然我们不想要所有这些重复项,所以让我们只收集不同的:

START tag=node:tags_fulltext('keyword')
MATCH tag<-[:TaggedWith]-item
RETURN collect(distinct tag) AS Tags, collect(distinct item) AS Items

--------------------------------------------
| tags | items |
--------------------------------------------
| red, blue, green | A, B, C, D, E, F, G |
--------------------------------------------

随着 Cypher 的运行,将其转换为 .NET 很容易:

var query = client
.Cypher
.StartWithNodeIndexLookup("tag", "tags_fulltext", keyword)
.Match("tag<-[:TaggedWith]-item")
.Return((tag, item) => new
{
Tags = tag.CollectDistinct<Tag>(),
Items = item.CollectDistinct<Item>()
});

总结

  1. 始终从 Cypher 开始
  2. 始终从 Cypher 开始
  3. 当您使用 Cypher 时,.NET 实现应该几乎是一对一的

有问题吗?

我在没有 VS 支持的文本框中输入了所有这些代码,而且我还没有测试过任何代码。如果出现崩溃,请在我们的问题页面上报告完整异常文本和查询。跟踪这里的崩溃很难。在没有完整异常文本、消息、堆栈跟踪等的情况下跟踪崩溃只会消耗我的时间,因为它使调试变得更加困难,并且减少了我可以花在其他方面帮助您的时间。

关于neo4jclient - 如何在 neo4j .net 客户端中使用密码查询返回两个集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15658376/

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