如果返回节点具有某种类型,则执行其他匹配

时间:2018-11-19 18:05:56

标签: neo4j cypher

我有一个看起来像这样的模型

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 :(得分:2)

原始答案

创建图形

为便于进一步解答和解决方案,我注意到了我的图形创建语句:

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行定义了模式“ Player戴有Armor,它是ArmorSet的一部分”。
  • 第3行在第4行中引入了排除变量“ missing缺少Player”所必需的变量Armor
  

“ WITH子句允许将查询零件链接在一起,将一个零件的结果传递给另一个零件,以用作下一个起点或条件。” (摘自Neo4j developers manual, WITH clauses chapter

  • 已识别的丢失Armor的第6行检索提供Quest的{​​{1}}
  • 第7行呈现所需的输出

结果

Npc

关于您的评论的扩展名

如果要确定只能由╒═════════╤═══════════╤══════════════════╕ │"npcName"│"questName"│"missingArmorName"│ ╞═════════╪═══════════╪══════════════════╡ │"NPC II" │"Quest II" │"Helmet" │ ├─────────┼───────────┼──────────────────┤ │"NPC I" │"Quest I" │"Boots" │ └─────────┴───────────┴──────────────────┘ 检索的Armor,那么我们必须通过标签Quest并根据相关关系{{1}来增强您的模型}。

创建图形

Monster

graph3

解决方案

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);

答案 1 :(得分:0)

Neo4j中的coalesce函数可用于压缩多个变量以使用最相关的非null值。

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

因此,在此示例中,合并将返回source的值(如果它们为1),否则将移至下一个重复并重复。如果所有值都为null,则将返回null。