如何将非唯一的父子关系表示为图?

时间:2019-05-08 06:30:43

标签: neo4j arangodb

我想看看是否有一种方法可以在图数据库平台(例如neo4j或arangodb)中表示/建模嵌套的父子关系。

特别是,我正在尝试为多个合同的承包商/分包商关系建模:

example contract relations image link

我可以看到使用父代和合同都代表的表格来完成此操作。我看不到如何在图形中执行此操作,因为可以有多个A-B关系,但是对于不同的合同。

1 个答案:

答案 0 :(得分:0)

使用ArangoDB

这里最好的做法是创建三个集合,并且我创建了一些示例数据和示例查询以向您展示其工作方式。

  • 合同:包含合同的文档集合
  • companies:包含公司的文档集合
  • company_contracts:包含合同和公司之间联系的边缘集合

目标是将合同和公司存储在各自的集合中,然后将关系hps存储在company_contracts边缘集合中。

由于这些公司可在多个合同中重复使用,因此有必要能够根据合同代码过滤关系。

每个合同都有一个名为code的密钥,其中包含该合同的标识符(例如,“合同1”的code1)。 注意:我还为每个公司添加了一个code字段,但这对于本示例不是必需的。

添加到company_contracts边缘集合的每个关系都将添加一个密钥,以标识该边缘用于什么合同,该密钥称为contract_code

这将在您的AQL查询中使用,以确保您仅选择与所讨论合同相关的边。

要创建基础数据,请在arangodsh工具中运行此脚本,然后启动它,然后在提供密码并连接好之后,只需将该文本块粘贴到其中即可创建示例集合并加载一些基本数据。

var contracts = db._create("contracts");
var companies = db._create("companies");
var company_contracts = db._createEdgeCollection("company_contracts");

var contract_1 = contracts.save({_key: "1", title:"Contract 1", code: 1})._id;
var contract_2 = contracts.save({_key: "2", title:"Contract 2", code: 2})._id;
var contract_3 = contracts.save({_key: "3", title:"Contract 3", code: 3})._id;

var company_a = companies.save({_key: "a", title:"Company A", code: "A"})._id;
var company_b = companies.save({_key: "b", title:"Company B", code: "B"})._id;
var company_c = companies.save({_key: "c", title:"Company C", code: "C"})._id;
var company_d = companies.save({_key: "d", title:"Company D", code: "D"})._id;
var company_e = companies.save({_key: "e", title:"Company E", code: "E"})._id;

company_contracts.save(contract_1, company_a, { contract_code: 1});
company_contracts.save(company_a, company_c, { contract_code: 1});
company_contracts.save(company_a, company_b, { contract_code: 1});
company_contracts.save(company_c, company_d, { contract_code: 1});
company_contracts.save(company_c, company_e, { contract_code: 1});

company_contracts.save(contract_2, company_c, { contract_code: 2});
company_contracts.save(contract_2, company_a, { contract_code: 2});
company_contracts.save(company_a, company_b, { contract_code: 2});
company_contracts.save(company_c, company_d, { contract_code: 2});

company_contracts.save(contract_3, company_b, { contract_code: 3});
company_contracts.save(company_b, company_c, { contract_code: 3});
company_contracts.save(company_b, company_a, { contract_code: 3});

完成此操作后,这是一个AQL查询示例,可用于查找给定合同代码的所有关系:

LET contract_id = FIRST(FOR d IN contracts FILTER d.code == @contract_code RETURN d._id)

FOR v, e, p IN 1..10 OUTBOUND contract_id company_contracts
FILTER p.edges[*].contract_code ALL == @contract_code
RETURN p

如果将1的值作为contract_code参数的值,则将得到示例文档所示的结果,并且如果您提供值23将会显示这些结果。

该查询通过执行以下两项操作起作用:

  • LET查询可找到您感兴趣的合同的_id
  • 然后,GRAPH查询将查找该合同中的所有出站连接,并将过滤器应用于该合同中每个路径中的ALL个边,以确保每个边都有一个{{1} }与您使用的合同代码匹配的键

company_code条件确保您仅获得与合同有关的优势。

在合同1的结果的ArangoDB图形查看器中,结果视图如下所示:

Sample result for Contract 1