如何在不使用客户端 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 为 V123V456 的一对事物为例。如果他们满足 $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。