如何在不使用客户端 API 的情况下从 Grakn 导出边缘列表
How to export edgelist from Grakn without using client APIs
我正在尝试从 grakn 导出边。我可以像这样使用 Python 客户端来做到这一点:
edge_query = "match $c2c($c1, $c2) isa c2c; $c1 has id $id1; $c2 has id $id2;get $id1,$id2;"
with open(f"grakn.edgelist","w") as outfile:
with GraknClient(uri="localhost:48555") as client:
with client.session(keyspace=KEYSPACE) as session:
with session.transaction().read() as read_transaction:
answer_iterator = read_transaction.query(edge_query)
for answer in tqdm(answer_iterator):
id1 = answer.get("id1")
id2 = answer.get("id2")
outfile.write(f"{id1.value()} {id2.value()} \n")
编辑:对于每个 Relation
,我想成对导出实体。输出可以是一对 Grakn ID。
我可以忽略关系或实体的属性。
导出到边缘似乎是一项常见任务。在 Grakn 中有没有更好的方法(更优雅、更快、更高效)?
只要关系类型 c2c
总是有两个角色扮演者,这就有效。但是,这将为每个 $c1, $c2
生成两条边,这可能不是您想要的。
让我们以 ID 为 V123
和 V456
的一对事物为例。如果他们满足 $c2c($c1, $c2) isa c2c;
和 $c1 = V123
和 $c2 = V456
那么他们也将满足与 $c1 = V456
和 $c2 = V123
相同的模式。 Grakn 将 return 满足您查询的 $c1, $c2
的所有组合,因此对于这个 c2c
关系,您将得到两个答案。
假设这不是你想要的,如果 $c1
和 $c2
在关系 c2c
中扮演不同的角色(可能暗示有方向到边缘)然后尝试改变查询,将角色添加到:
edge_query = "match $c2c(role1: $c1, role2: $c2) isa c2c; $c1 has id $id1; $c2 has id $id2; get $id1,$id2;"
如果它们都扮演相同的角色(暗示无向边),那么我们需要在逻辑上做一些不同的事情。要么将边缘存储为一组 ID 集以轻松删除重复项,要么考虑使用 Python ConceptAPI,如下所示:
relation_query = "match $rc2c isa c2c;get;"
with open(f"grakn.edgelist","w") as outfile:
with GraknClient(uri="localhost:48555") as client:
with client.session(keyspace=KEYSPACE) as session:
with session.transaction().read() as read_transaction:
answer_iterator = read_transaction.query(relation_query)
for answer in answer_iterator:
relation_concept = answer.get("rc2c")
role_players_map = relation_concept.role_players_map()
role_player_ids = set()
for role, thing in role_players_map.items():
# Here you can do any logic regarding what things play which roles
for t in thing:
role_player_ids.add(t.id) # Note that you can retrieve a concept id from the concept object, you don't need to ask for it in the query
outfile.write(", ".join(role_player_ids) + "\n")
当然,我不知道你在用生成的边缘列表做什么,但为了完整起见,更像 Grakn 的方式是将 Relation 视为第一个 class 公民,因为它表示 Grakn 知识模型中的超边,在这种情况下,我们会将关系的角色视为边。这意味着当我们有三元或 N 元关系时,我们不会陷入困境。我们可以通过更改查询来做到这一点:
match $c2c($c) isa c2c; get;
然后在结果中我们得到 $c2c
和 $c
的 id。
我正在尝试从 grakn 导出边。我可以像这样使用 Python 客户端来做到这一点:
edge_query = "match $c2c($c1, $c2) isa c2c; $c1 has id $id1; $c2 has id $id2;get $id1,$id2;"
with open(f"grakn.edgelist","w") as outfile:
with GraknClient(uri="localhost:48555") as client:
with client.session(keyspace=KEYSPACE) as session:
with session.transaction().read() as read_transaction:
answer_iterator = read_transaction.query(edge_query)
for answer in tqdm(answer_iterator):
id1 = answer.get("id1")
id2 = answer.get("id2")
outfile.write(f"{id1.value()} {id2.value()} \n")
编辑:对于每个 Relation
,我想成对导出实体。输出可以是一对 Grakn ID。
我可以忽略关系或实体的属性。
导出到边缘似乎是一项常见任务。在 Grakn 中有没有更好的方法(更优雅、更快、更高效)?
只要关系类型 c2c
总是有两个角色扮演者,这就有效。但是,这将为每个 $c1, $c2
生成两条边,这可能不是您想要的。
让我们以 ID 为 V123
和 V456
的一对事物为例。如果他们满足 $c2c($c1, $c2) isa c2c;
和 $c1 = V123
和 $c2 = V456
那么他们也将满足与 $c1 = V456
和 $c2 = V123
相同的模式。 Grakn 将 return 满足您查询的 $c1, $c2
的所有组合,因此对于这个 c2c
关系,您将得到两个答案。
假设这不是你想要的,如果 $c1
和 $c2
在关系 c2c
中扮演不同的角色(可能暗示有方向到边缘)然后尝试改变查询,将角色添加到:
edge_query = "match $c2c(role1: $c1, role2: $c2) isa c2c; $c1 has id $id1; $c2 has id $id2; get $id1,$id2;"
如果它们都扮演相同的角色(暗示无向边),那么我们需要在逻辑上做一些不同的事情。要么将边缘存储为一组 ID 集以轻松删除重复项,要么考虑使用 Python ConceptAPI,如下所示:
relation_query = "match $rc2c isa c2c;get;"
with open(f"grakn.edgelist","w") as outfile:
with GraknClient(uri="localhost:48555") as client:
with client.session(keyspace=KEYSPACE) as session:
with session.transaction().read() as read_transaction:
answer_iterator = read_transaction.query(relation_query)
for answer in answer_iterator:
relation_concept = answer.get("rc2c")
role_players_map = relation_concept.role_players_map()
role_player_ids = set()
for role, thing in role_players_map.items():
# Here you can do any logic regarding what things play which roles
for t in thing:
role_player_ids.add(t.id) # Note that you can retrieve a concept id from the concept object, you don't need to ask for it in the query
outfile.write(", ".join(role_player_ids) + "\n")
当然,我不知道你在用生成的边缘列表做什么,但为了完整起见,更像 Grakn 的方式是将 Relation 视为第一个 class 公民,因为它表示 Grakn 知识模型中的超边,在这种情况下,我们会将关系的角色视为边。这意味着当我们有三元或 N 元关系时,我们不会陷入困境。我们可以通过更改查询来做到这一点:
match $c2c($c) isa c2c; get;
然后在结果中我们得到 $c2c
和 $c
的 id。