在图形数据库中建模介词关系的正确方法是什么? (例如,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"
基本上,数据模型的设计与业务关注点一样多(即,您要查询什么)。
假设我想要一个包含购物者、杂货店和农产品的数据库。例如,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"
基本上,数据模型的设计与业务关注点一样多(即,您要查询什么)。