如何从 Cypher 查询反序列化关系,保留动态关系类型?

问题描述 投票:0回答:1

让我们从一个示例数据集开始。有 2 个节点和 2 个关系,它们之间的关系类型不同。节点和关系都有属性。不要过多关注语义,这是源自我无法直接在此处展示的用例。

create (a:AlphaNode {name: "Alice"} )
create (b:BetaNode {name: "Bob"} )
create (a)-[:HAS {really: false} ]->(b)
create (a)-[:NEEDS {timespan: 42} ]->(b)

现在,我想按照以下方式运行查询:

match (a:AlphaNode)-[r:HAS|NEEDS]->(b:BetaNode)
// where etc ... (not important in the example)
return a, r, b

这将返回 2 个结果集,其中节点是相同的,只有

r
表示的关系在结果集之间会有所不同。

我使用 Neo4jClient 的 C# 代码应如下所示:

client.Cypher
    .Match("(a:AlphaNode)-[r:HAS|NEEDS]->(b:BetaNode)")
    .ReturnDistinct((a, r, b) => new
    {
        A = a.As<AlphaNode>(),
        R = r.As<SomeRelationship>(),
        B = b.As<BetaNode>()
    })
    // .ResultAsync etc. (not important, here)
    ;

现在,我遇到了

SomeRelationship
的问题。当然,我可以将其设为 POCO/DTO,但这样我就无法访问关系类型(
HAS
NEEDS
)。我在文档中找不到好的提示或示例,我发现的只是对
Relationship
RelationshipInstance
RelationshipReference
类的提示(它们具有关系类型,但这不是从数据库,而是通过类继承来固定),但我不能真正让它们(或者更准确地说是它们的后代)像这样工作(即使对于单个关系,但动态才是真正的点,在这里)。

有没有一种方法可以使用动态关系 POCO 比使用一些奇怪的继承更干净地完成此操作,这些继承主要是为了用无参数的构造函数替换构造函数?我认为这些课程的意图与我的预期有点不同。不要误会我的意思,我很想继承一个关系型基类,但是基类必须从响应中提供关系类型,并且首先要有一个无参数构造函数。

relationship neo4jclient
1个回答
0
投票

我会给出一个答案,因为我遇到了与你类似的问题。根据您的需要,我有几个解决方案。

返回属性字典和标签

此方法要求您修改返回的匿名对象以容纳

Dictionary<string, string>
中的所有关系属性以及
string
中的关系类型。

client.Cypher
    .Match("(a:AlphaNode)-[r:HAS|NEEDS]->(b:BetaNode)")
    .ReturnDistinct((a, r, b) => new
    {
        A = a.As<AlphaNode>(),
        RelationshipProperties = r.CollectAs<Dictionary<string, string>>(),
        RelationshipType = r.Type(),
        B = b.As<BetaNode>()
    }).ResultsAsync;

以 JSON 形式返回

对于您的情况来说可能有点过分了,但对于我的用例来说这是必要的。您可以使用以下查询将整个路径(节点和关系)作为 JSON 字符串返回。然后,您可以根据需要将其序列化到您的模型中。

client.Cypher
    .Match("path = (a:AlphaNode)-[r:HAS|NEEDS]->(b:BetaNode)")
    .Return<string>("path")
    .ResultsAsync;
© www.soinside.com 2019 - 2024. All rights reserved.