Оригинальный ответ
Создание вашего графика
Для простоты возможных дальнейших ответов и решений отмечу мое утверждение создания графа:
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](https://i.stack.imgur.com/bLWbb.png)
Решение
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](https://i.stack.imgur.com/vkld1.png)
Решение
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" │
└─────────┴───────────┴──────────────────┘