neo4j - 如何将非唯一的父子关系表示为图形?
问题描述
我想看看是否有一种方法可以在 neo4j 或 arangodb 等图形数据库平台中表示/建模嵌套的父子关系。
特别是,我正在尝试对多个合同的承包商/分包商关系进行建模:
我可以看到如何使用代表父级和合同的表来完成此操作。我看不到如何在图表中执行此操作,因为可以有多个 AB 关系但针对不同的合同。
解决方案
使用 ArangoDB
这里最好的做法是创建三个集合,我创建了一些示例数据和示例查询来向您展示它是如何工作的。
- 合同:包含合同的文档集合
- 公司:包含公司的文档集合
- company_contracts:包含合同和公司之间连接的边缘集合
目标是将您的合同和公司存储在它们各自的集合中,然后将关系存储在 company_contracts 边缘集合中。
由于公司在多个合同中重复使用,因此有必要能够根据合同代码过滤关系。
每个合同都有一个名为的密钥code
,其中包含该合同的标识符(例如,“合同 1”有一个code
of 1
)。注意:我还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
参数的值传递,您将获得示例文档所示的结果,并且如果您提供值2
或3
它将显示这些结果。
查询通过做两件事来工作:
LET
查询找到_id
您感兴趣的合同- 然后,
GRAPH
查询从该合约中找到所有出站连接,并将过滤器应用于从该合约ALL
出来的每条路径中的边,确保每条边都有一个company_code
与您正在使用的合约代码匹配的密钥
此FILTER ... ALL
条件可确保您仅获得与合同相关的优势。
在 ArangoDB 图形查看器中,合同 1 的结果视图如下所示:
推荐阅读
- javascript - JavaScript,无法读取 null 的属性“映射””,嵌套 ForEach?
- javascript - 如何使用 jquery / javascript 有条件地更改自定义属性的属性
- python - Python:对列表中已有的项目进行分组并将它们反转
- javascript - Chart.js 中的同一个甜甜圈图是否可以有不同的厚度?
- python - matplotlib:如何添加像素值范围的图例?
- azure-logic-apps - 通过逻辑应用创建 Azure 服务总线主题和订阅
- python - 使用 pandas 转换年度数据
- php - 在没有已知_id的情况下按列名在mongodb中查找数据
- c# - C# OpenXML 插入的图像质量很差,模糊
- microsoft-dynamics - 时间条目审批流程 Dynamics 365