выполнить дополнительное сопоставление, если возвращаемый узел имеет определенный тип - PullRequest
0 голосов
/ 19 ноября 2018

У меня есть модель, которая выглядит следующим образом

enter image description here

Я хочу, чтобы игрок рекомендовал квест, который позволил бы завершить его набор брони. Я делаю этот cypher запрос для возврата отношения quest -> boots.

MATCH (w:Armor)<-[:WEARS]-(p:Player)
MATCH (w)-[:PART_OF]->(set:ArmorSet)
MATCH (missing)-[:PART_OF]->(set)
MATCH (missing)<--(anything)
WHERE NOT (p)-[:WEARS]->(missing)
RETURN missing, anything

Но как настроить этот запрос, чтобы он возвращал NPC, который дает квест, если boots является наградой за квест? В основном я хочу проверить, что если узел имеет тип quest, то я должен вернуть npc, который дает этот квест.

Как этого добиться в Neo4j?

Ответы [ 2 ]

0 голосов
/ 20 ноября 2018

Функция coalesce в Neo4j может использоваться для сжатия нескольких переменных, чтобы использовать наиболее релевантное ненулевое значение.

MATCH (w:Armor)<-[:WEARS]-(p:Player)
MATCH (w)-[:PART_OF]->(set:ArmorSet)
MATCH (missing)-[:PART_OF]->(set)
MATCH (missing)<--(anything)
WHERE NOT (p)-[:WEARS]->(missing)
OPTIONAL MATCH (anything)<-[:GIVES]-(source)
RETURN missing, coalesce(source, anything) as source

Таким образом, в этом примере coalesce вернет значение source, если их значение равно единице, в противном случае оно перейдет к следующему и повторится. Если все значения равны нулю, возвращается ноль.

0 голосов
/ 20 ноября 2018

Оригинальный ответ

Создание вашего графика

Для простоты возможных дальнейших ответов и решений отмечу мое утверждение создания графа:

CREATE
  (player:Player {name: 'Player'}),
  (shield:Armor {name: 'Shield'}),
  (armor:Armor {name: 'Armor'}),
  (gauntlets:Armor {name: 'Gauntlets'}),
  (boots:Armor {name: 'Boots'}),
  (helmet:Armor {name: 'Helmet'}),
  (dragonSet:ArmorSet {name: 'Dragon Set'}),
  (quest1:Quest {name: 'Quest I'}),
  (quest2:Quest {name: 'Quest II'}),
  (npc1:Npc {name: 'NPC I'}),
  (npc2:Npc {name: 'NPC II'}),
  (player)-[:WEARS]->(shield)-[:PART_OF]->(dragonSet),
  (player)-[:WEARS]->(armor)-[:PART_OF]->(dragonSet),
  (player)-[:WEARS]->(gauntlets)-[:PART_OF]->(dragonSet),
  (npc1)-[:PROVIDES]->(quest1)-[:REWARDS]->(boots)-[:PART_OF]->(dragonSet),
  (npc2)-[:PROVIDES]->(quest2)-[:REWARDS]->(helmet)-[:PART_OF]->(dragonSet);

В строках 2–12 создаются узлы, а в строках 13–17 - отношения между ними.

graph2

Решение

MATCH
  (player:Player)-[:WEARS]->(armor:Armor)-[:PART_OF]->(dragonSet:ArmorSet),
  (missing)-[:PART_OF]->(dragonSet)
  WHERE NOT (player)-[:WEARS]->(missing:Armor)
WITH DISTINCT missing
MATCH (npc:Npc)-[:PROVIDES]->(quest:Quest)-[:REWARDS]->(missing)
RETURN npc.name AS npcName, quest.name AS questName, missing.name AS missingArmorName;

Объяснение

  • Строка 2 определяет шаблон «A Player носит Armor, который является частью ArmorSet».
  • В строке 3 вводится переменная missing, необходимая для исключения "Player носит отсутствующий Armor" в строке 4

«Предложение WITH позволяет объединять части запроса, передавая результаты одной из них, чтобы использовать ее в качестве отправных точек или критериев для следующей». (Взято из Руководства для разработчиков Neo4j, глава WITH )

  • Строка 6 для обнаруженных пропавших без вести Armor s возвращает Quest, предоставляя Npc s
  • Строка 7 отображает желаемый результат

Результат

╒═════════╤═══════════╤══════════════════╕
│"npcName"│"questName"│"missingArmorName"│
╞═════════╪═══════════╪══════════════════╡
│"NPC II" │"Quest II" │"Helmet"          │
├─────────┼───────────┼──────────────────┤
│"NPC I"  │"Quest I"  │"Boots"           │
└─────────┴───────────┴──────────────────┘

Расширение вашего комментария

Если важно определить Armor с, которые можно извлечь только с помощью Quest с, мы должны улучшить вашу модель с помощью метки Monster с соответствующим соотношением RANDOM_DROPS.

Создание вашего графика

CREATE
  (player:Player {name: 'Player'}),
  (shield:Armor {name: 'Shield'}),
  (armor:Armor {name: 'Armor'}),
  (gauntlets:Armor {name: 'Gauntlets'}),
  (boots:Armor {name: 'Boots'}),
  (helmet:Armor {name: 'Helmet'}),
  (dragonSet:ArmorSet {name: 'Dragon Set'}),
  (quest1:Quest {name: 'Quest I'}),
  (quest2:Quest {name: 'Quest II'}),
  (npc1:Npc {name: 'NPC I'}),
  (npc2:Npc {name: 'NPC II'}),
  (monster1:Monster {name: 'Monster I'}),
  (monster2:Monster {name: 'Monster II'}),
  (player)-[:WEARS]->(shield)-[:PART_OF]->(dragonSet),
  (player)-[:WEARS]->(armor)-[:PART_OF]->(dragonSet),
  (player)-[:WEARS]->(gauntlets)-[:PART_OF]->(dragonSet),
  (npc1)-[:PROVIDES]->(quest1)-[:REWARDS]->(boots)-[:PART_OF]->(dragonSet),
  (npc2)-[:PROVIDES]->(quest2)-[:REWARDS]->(helmet)-[:PART_OF]->(dragonSet),
  (monster2)-[:RANDOM_DROPS]->(boots),
  (monster1)-[:RANDOM_DROPS]->(gauntlets),
  (monster1)-[:RANDOM_DROPS]->(shield),
  (monster1)-[:RANDOM_DROPS]->(armor);

graph3

Решение

MATCH
  (player:Player)-[:WEARS]->(armor:Armor)-[:PART_OF]->(dragonSet:ArmorSet),
  (missing)-[:PART_OF]->(dragonSet)
  WHERE NOT (player)-[:WEARS]->(missing:Armor)
WITH DISTINCT missing
MATCH (npc:Npc)-[:PROVIDES]->(quest:Quest)-[:REWARDS]->(missing)
  WHERE NOT (:Monster)-[:RANDOM_DROPS]->(missing)
RETURN npc.name AS npcName, quest.name AS questName, missing.name AS missingArmorName;

Результат

╒═════════╤═══════════╤══════════════════╕
│"npcName"│"questName"│"missingArmorName"│
╞═════════╪═══════════╪══════════════════╡
│"NPC II" │"Quest II" │"Helmet"          │
└─────────┴───────────┴──────────────────┘
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...