Neo4j标签与节点属性

时间:2018-03-28 18:55:36

标签: neo4j cypher world-of-warcraft

我正在学习Neo4j,作为一个测试项目,我使用从dev.battle.net检索到的数据为我的所有角色绘制了我的魔兽世界公会。

明显的标签是角色和公会,但其他一些很难说。 每个角色都有一个等级,每个等级有2-4个专精,每个专业都填充3个角色中的一个(坦克,治疗师,伤害)。

我的测试查询是......

  • 查找公会内的所有坦克" ABC"。
  • 在Realm" DEF"上找到所有德鲁伊(Class)。
  • 查找同一个公会中的所有角色" GHI"。

我的假设是,角色,专业化,类和领域也应该是标签,并且关系具体化。

MATCH (:Tank)-[:RoleFor]->(s:Spec)<-[h:Has]-(c:Character)-[:Member]->(g:Guild)
WHERE h.ItemLevel > 900 and g.Name like 'TestGuild1'
RETURN c,h,s

而不是......

MATCH (c:Character)
Where (c.Class like "Druid" and c.Spec3ItemLevel > 900) Or (c.Class like "Death Knight" and c.Spec1ItemLevel > 900)
return c

认为第一个会更快,除非它必须从(:Spec)<-[]-(:Character)加载所有关系才能过滤它们。从查询的角度来看,它至少看起来更干净。谁能证实这一点?

有数百万个角色,数千个公会,可能超过100个公会,但是课程数量(12个)和规格(36个)要少得多。

1 个答案:

答案 0 :(得分:3)

如果我们假设您的2个示例(包含一些语法错误:like不是Cypher运算符)代表您的所有用例,那么像您的第一个数据模型似乎是合适的。您只需添加适当的索引(或唯一性约束),以避免扫描大量数据以启动查询。

以下是与您的2个示例相对应的修改后的查询:

MATCH (:Tank)-[:ROLE_FOR]->(s:Spec)<-[h:HAS_SPEC]-(c:Character)-[:MEMBER_OF]->(g:Guild)
WHERE h.itemLevel > 900 AND g.name = 'TestGuild1'
RETURN c, h, s;

MATCH (s:Spec)<-[h:HAS_SPEC]-(c:Character)-[:HAS_CLASS]->(cl:Class)
WHERE s.spec3ItemLevel > 900 AND cl.name IN ['Druid', 'Death Knight']
RETURN c;

你应该至少有的索引

  • :Guild(name)
  • :Class(name)
  • :Spec(spec3ItemLevel)