#cypher #agens-graph
#шифр #график агенса
Вопрос:
Предположим, мы моделируем пары с двумя метками вершин, женской и мужской, и с одной меткой ребра, dates. Направление ребра всегда от женского к мужскому.
Список ожидаемых результатов запроса представляет собой пары, где существует ненаправленный путь от начальной вершины к вершинам каждой пары, отличный.
Другими словами, результат должен содержать список ребер связанных компонентов графа, где присутствует данная вершина.
Пожалуйста, обратите внимание, что могут возникать циклы, если исходный график преобразуется в ненаправленный граф.
Критерий фильтрации: { name: 'Adam' }
Ожидаемый набор результатов:
Alice-[:dates]->Adam
Alice-[:dates]->Bob
Chloe-[:dates]->Bob
...
Eve-[:dates]->Edgar
Uhura-[:dates]->Spock
не является частью набора результатов, поскольку нет связи между Адамом и (Ухурой или Споком).
Следующее решение работает, но у него низкая производительность, поэтому его нельзя использовать в рабочей среде:
match path = ()-[:dates*]-()
where any(node in to_jsonb(nodes(path)) where node.properties.name = 'Adam')
return distinct path;
(Или return distinct edges(path)
, но AgensBrowser не любит возвращать ребра пути).
Не могли бы вы, пожалуйста, помочь мне с некоторыми советами для лучшего решения? Спасибо.
Тестовые данные:
create
(alice: female { name: 'Alice'}),
(barbara: female { name: 'Barbara'}),
(chloe: female { name: 'Chloe'}),
(diane: female { name: 'Diane'}),
(eve: female { name: 'Eve'}),
(uhura: female { name: 'Uhura'}),
(adam: male { name: 'Adam'}),
(bob: male { name: 'Bob'}),
(charles: male { name: 'Charles'}),
(daniel: male { name: 'Daniel'}),
(edgar: male { name: 'Edgar'}),
(spock: male { name: 'Spock'})
create (alice)-[:dates]->(adam),
(alice)-[:dates]->(bob),
(barbara)-[:dates]->(bob),
(barbara)-[:dates]->(charles),
(barbara)-[:dates]->(edgar),
(chloe)-[:dates]->(bob),
(chloe)-[:dates]->(daniel),
(chloe)-[:dates]->(edgar),
(diane)-[:dates]->(edgar),
(eve)-[:dates]->(edgar),
(uhura)-[:dates]->(spock);
Ответ №1:
Я попытался воспроизвести ваш запрос в Agensgraph, но последний запрос соответствия у меня не сработал, поэтому я не смог проверить его объяснение.
Вот запрос, который я сделал, чтобы получить тот же результат, который вы хотите.
match (f:female)<-[r:dates*]->(m:male{name:'Adam'}) with distinct f
match p = ((f)-[:dates]->(m:male)) return p;
--------------------------------------------------------------------------
[female[73.1]{"name": "Alice"},dates[71.23][73.1,74.1]{},male[74.1]{"name": "Adam"}]
[female[73.1]{"name": "Alice"},dates[71.24][73.1,74.2]{},male[74.2]{"name": "Bob"}]
[female[73.2]{"name": "Barbara"},dates[71.25][73.2,74.2]{},male[74.2]{"name": "Bob"}]
[female[73.2]{"name": "Barbara"},dates[71.26][73.2,74.3]{},male[74.3]{"name": "Charles"}]
[female[73.2]{"name": "Barbara"},dates[71.27][73.2,74.5]{},male[74.5]{"name": "Edgar"}]
[female[73.3]{"name": "Chloe"},dates[71.28][73.3,74.2]{},male[74.2]{"name": "Bob"}]
[female[73.3]{"name": "Chloe"},dates[71.29][73.3,74.4]{},male[74.4]{"name": "Daniel"}]
[female[73.3]{"name": "Chloe"},dates[71.30][73.3,74.5]{},male[74.5]{"name": "Edgar"}]
[female[73.4]{"name": "Diane"},dates[71.31][73.4,74.5]{},male[74.5]{"name": "Edgar"}]
[female[73.5]{"name": "Eve"},dates[71.32][73.5,74.5]{},male[74.5]{"name": "Edgar"}]
(10 rows)
Честно говоря, я не очень уверен в производительности приведенного выше запроса при огромном объеме данных.
Пожалуйста, оставьте мне отзыв после выполнения запроса.
Отредактировано 25 марта.
Может ли это быть решением для вашего случая?
match p = allshortestpaths( (f:female)<-[r:dates*]->(m:male) )
where any(node in to_jsonb(nodes(p)) where node.properties.name starts with 'Adam' )
return p;
Комментарии:
1. Спасибо, ваше решение работает для примера, и ваши усилия высоко ценятся. В реальных случаях у нас есть более сложные критерии, чем {name:’Adam’}, поэтому мы могли бы использовать только
any(node in to_jsonb(nodes(path)) where ...)
иall(node in to_jsonb(nodes(path)) where ...)
стиль выражений. Это приводило к снижению производительности, особенно если на неориентированном пути был цикл. Допустим, у нас есть условие «имя начинается с Adam» вместо «имя равно Adam». Знаете ли вы эффективное решение для этого? Спасибо.2. Поскольку ответ правильный для исходной задачи, я отмечу его как принятый. Однако, если бы кто-нибудь мог дать ответ на случай сложных условий (см. Мой последний комментарий), это было бы здорово. Спасибо.