Предотвращение дублирования SIMILAR-отношений при использовании algo.simility.jaccard для постоянно обновляемых данных - PullRequest
0 голосов
/ 12 декабря 2018

Я вычисляю индекс подобия Жакара для категории узлов в графе, используя алгоритм algo.similarity.jaccard из библиотеки алгоритма графа Neo4j.После вычисления сходства по Джакарду и указания отсечки я сохраняю метрику в отношении между узлами (это особенность алгоритма).Я пытаюсь увидеть изменение графика с течением времени, когда получаю новые данные для добавления в график (я буду перезагружать свой CSV-файл новыми данными и объединять их в новые узлы / отношения).

ПроблемаЯ предвижу, что, как только я снова запустю алгоритм Jaccard с обновленным графиком, он создаст дублирующиеся отношения.Это пример документации Neo4j кода, который я использую:

MATCH (p:Person)-[:LIKES]->(cuisine)
WITH {item:id(p), categories: collect(id(cuisine))} as userData
WITH collect(userData) as data
CALL algo.similarity.jaccard(data, {topK: 1, similarityCutoff: 0.1, write:true})
YIELD nodes, similarityPairs, write, writeRelationshipType, writeProperty, min, max, mean, stdDev, p25, p50, p75, p90, p95, p99, p999, p100
RETURN nodes, similarityPairs, write, writeRelationshipType, writeProperty, min, max, mean, p95

Есть ли способ указать, что я не хочу иметь дублирующиеся отношения при каждом запуске этого кода с обновленным графиком?Вручную, я бы использовал MERGE вместо CREATE, но, видя, что это алгоритм из библиотеки, я не уверен, как это сделать.К вашему сведению, у меня не будет возможности добавлять изменения в библиотечный плагин, и, похоже, нет способа сохранить отношения под другой меткой, такой как SIMILARITY2.

1 Ответ

0 голосов
/ 13 декабря 2018

Существует как минимум 2 способа избежать дублирования отношений из нескольких вызовов на algo.similarity.jaccard:

  1. Удалить существующие отношения (по умолчанию они имеют тип SIMILAR) до того, каккаждый звонок.Это, вероятно, самый простой подход.

  2. Пропустите параметр write:true при выполнении вызовов (чтобы процедура вообще не создавала отношений) и напишите свой собственный код Cypher вПри необходимости создайте отношения, которые еще не существуют (с использованием MERGE).

[ОБНОВЛЕНО]

Вот пример второго подхода (с использованием algo.similarity.jaccard.streamвариант процедуры, который дает более полезные значения для наших целей):

MATCH (p:Person)-[:LIKES]->(cuisine)
WITH {item:id(p), categories: collect(id(cuisine))} as userData
WITH collect(userData) as data
CALL algo.similarity.jaccard.stream(data, {topK: 1, similarityCutoff: 0.1})
YIELD item1, item2, similarity
WHERE item1 < item2
WITH algo.getNodeById(item1) AS n1, algo.getNodeById(item2) AS n2, similarity
MERGE (n1)-[s:SIMILAR]-(n2)
SET s.score = similarity
RETURN *

Поскольку процедура будет возвращать одну и ту же пару узлов дважды (с одинаковым similarity счетом), предложение WHEREиспользуется для фильтрации одной из пар, чтобы ускорить обработку.Служебная функция algo.getNodeById() используется для получения узла по его собственному идентификатору.А в шаблоне отношений предложения MERGE не указывается значение для score, поэтому оно будет соответствовать существующим отношениям, даже если оно имеет другое значение.Предложение SET для установки score ставится после MERGE, что также помогает обеспечить актуальность значения.

...