Как экспортировать edgelist из Grakn без использования клиентских API - PullRequest
1 голос
/ 18 февраля 2020

Я пытаюсь экспортировать края из гракн. Я могу сделать это с клиентом 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. Я могу игнорировать атрибуты отношения или сущности.

Экспорт в ребра кажется обычной задачей. Есть ли лучший способ (более элегантный, быстрый, эффективный) сделать это в Grakn?

1 Ответ

1 голос
/ 20 февраля 2020

Это работает до тех пор, пока тип отношения c2c всегда имеет двух игроков. Однако это даст два ребра для каждого $c1, $c2, что, вероятно, не то, что вам нужно.

Давайте возьмем пару вещей с идентификаторами V123 и V456. Если они удовлетворят $c2c($c1, $c2) isa c2c; с $c1 = V123 и $c2 = V456, то они также будут удовлетворять той же схеме, что и $c1 = V456 и $c2 = V123. Grakn вернет все комбинации $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;"

Если они оба играют одинаковую роль (подразумевая ненаправленные ребра), тогда нам нужно сделать что-то другое в нашей логике c. Либо сохраняйте ребра как наборы идентификаторов для удаления дубликатов без особых усилий, либо, возможно, рассмотрите возможность использования 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 как к первоклассному гражданину, поскольку он представляет собой гиперредж в модели знаний Grakn, в данном случае мы будет рассматривать роли отношения как ребра. Это означает, что мы не застряли, когда у нас есть троичные или N-арные отношения. Мы можем сделать это, изменив запрос:

match $c2c($c) isa c2c; get;

Затем в результате мы получим идентификатор $c2c и $c.

...