在图形数据库中建模介词关系的正确方法是什么? (例如,A 在 C 上做 B,X 通过 Z 购买 Y)

What is the right way to model prepositional relationships in a graph database? (e.g., A does B on C, X buys Y through Z)

假设我想要一个包含购物者、杂货店和农产品的数据库。例如,Billy's Grocery 供应胡萝卜和萝卜。爱丽丝的杂货店供应胡萝卜和小萝卜。 Jinh 从 Alice 的杂货店买胡萝卜,她从 Billy 的杂货店买萝卜。

"carrot"、"Jinh" 和 "Alice's Grocery" 似乎是三个节点。我知道 hyperedges,但据我所知,它们存在性能问题。将其中一个节点编码为关系(例如,关系 "buys_carrots_from")似乎是一种反模式。

有没有一种合理的方式来表示这种关系(Jinh 从爱丽丝的杂货店买胡萝卜)?或者这种类型的数据不能很好地转换为图形数据库?

只有 (:grocery)、(:product) 和 (:consumer) 节点

create (Billy_s:grocery{name:"Billy's"})
create (Alice_s:grocery{name:"Alice's"})
create (carrots:product)
create (turnips:product)
create (radishes:product)
create (Jinh:consumer)

您无法将其正确建模为图形。 (我知道我的代码只是伪代码)create (Jinh)-[BUYS]->(carrots) 仅表示 Jinh 可能从 Alice 那里购买胡萝卜。

所以我们需要一个中介,和往常一样,这个中介可以用来存储更多信息:价格

create (Billy_s_carrots:offer{price:0.45})
create (Billy_s_turnips:offer{price:1.12})
create (Alice_s_carrots:offer{price:0.42})
create (Alice_s_radises:offer{price:1.50})

create (Billy_s)-[:SUPPLIES]->(Billy_s_carrots)-[:WHICH_ARE]->(carrots)
create (Billy_s)-[:SUPPLIES]->(Billy_s_turnips)-[:WHICH_ARE]->->(turnips)
create (Alice_s)-[SUPPLIES]->(Alice_s_carrots)-[:WHICH_ARE]->(carrots)
create (Alice_s)-[SUPPLIES]->(Alice_s_radishes)-[:WHICH_ARE]->(radishes) 

现在如果

create (Jinh)-[:DESIRES]->(carrots) // and
create (Jinh)-[:DESIRES]->(turnips) 

He/she有选择省钱

create (Jinh)-[:BUYS]->(Alice_s_carrots) // and
create (Jinh)-[:BUYS]->(Billy_s_turnips) 

或者为了节省时间

create (Jinh)-[:BUYS]->(Billy_s_carrots) // and
create (Jinh)-[:BUYS]->(Billy_s_turnips) 

此题与类似。所以我试着按照同样的逻辑来回答它。

另一种方法是将 "Jinh bought carrots from Alice's Grocery" 中的 "Alice" 表示为 "bought" 的 属性。数据模型为:

为了便于说明,以下查询使用 Nebula Graph 开发的图查询语言 nGQL。

// define the schema
create tag person(name string)
create tag produce(name string)
create tag store(name string)
create edge bought(store string)
create edge supply(price double)

// insert the vertex
INSERT VERTEX person(name) VALUES 100:("Jinh");
INSERT VERTEX produce(name) VALUES 200:("carrot");
INSERT VERTEX produce(name) VALUES 201:("turnips");
INSERT VERTEX produce(name) VALUES 202:("radishe");
INSERT VERTEX store(name) VALUES 300:("Alice's");
INSERT VERTEX store(name) VALUES 301:("Bill's");


// insert the edge
INSERT EDGE bought(store) VALUES 100->200:("Alice's");
INSERT EDGE bought(store) VALUES 100->201:("Bill's");
INSERT EDGE supply(price) VALUES 300->200:(0.42);
INSERT EDGE supply(price) VALUES 300->202:(1.5);
INSERT EDGE supply(price) VALUES 301->200:(0.45);
INSERT EDGE supply(price) VALUES 301->201:(1.12);

要查找 Jinh 买了哪家商店的胡萝卜

> GO FROM 100 OVER bought where bought._dst==200 YIELD bought.store as store

查找"Angela"在"Alice's"

喜欢的杂货数量
> GO FROM 101 OVER bought WHERE bought.store = "Alice's"

基本上,数据模型的设计与业务关注点一样多(即,您要查询什么)。