如何将非唯一的父子关系表示为图形? [英] How to represent non unique parent-child relationship as graph?

查看:21
本文介绍了如何将非唯一的父子关系表示为图形?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想看看是否有一种方法可以在像neo4j或arangodb这样的图形数据库平台中表示/建模嵌套的父子关系.

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

I want to see if there is a way to represent/model a nested parent-child relationship in a graph db platform like neo4j or arangodb.

In particular, I am trying to model the contractor/subcontractor relations over multiple contracts:

example contract relations image link

I can see how this can be done using a table where both the parent and the contract are represented. I can't see how to do this in a graph since there can be multiple A-B relations but for different contracts.

解决方案

Using ArangoDB

The best thing to do here is create three collections, and I've created some sample data and sample queries to show you how it can work.

  • contracts: A document collection that contains contracts
  • companies: A document collection that contains companies
  • company_contracts: An edge collection that contains connections between contracts and companies

The goal is to store your contracts and companies in their respective collections and then store the relationshps in the company_contracts edge collection.

Because the companies are reused across multiple contracts, it will therefore be necessary to be able to filter on the relationships, based on the contract code.

Each contract has a key called code which contains an identifier for that contract (e.g. 'Contract 1' has a code of 1). Note: I've also added a code field to each company, but that's not necessarily required for this example.

Each relationship that is added to the company_contracts edge collection will have a key added to it to identify what contract that edge is for, and this key is called contract_code.

This will be used in your AQL query to ensure you only select edges related to your contract in question.

To create the base data, you run this script in the arangodsh tool, just start it and then once you've provided your password and are connected, just paste this block of text in to create the sample collections and load some base data.

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});

Once you've done that, this is an example AQL query you could use to find all relationships for a given contract code:

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

If you pass a value of 1 as the value for the contract_code parameter, you'll get the result as shown by your sample document, and if you provide the values 2 or 3 it will show those results.

The query works by doing two things:

  • The LET query finds the _id of the contract you're interested in
  • The GRAPH query then finds all outbound connections from that contract, and it applies a filter to ALL edges in each path coming out of that contract, ensuring every single edge has a company_code key that matches the contract code you're working with

This FILTER ... ALL condition ensures you only get edges related to your contract.

The view of the results looks like this in the ArangoDB graph viewer for the results for Contract 1:

这篇关于如何将非唯一的父子关系表示为图形?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆