Neo4j 标签与节点 属性
Neo4j Label vs. Node Property
我正在学习 Neo4j,作为一个测试项目,我正在使用从 dev.battle.net.
检索到的数据为我的所有角色绘制我的魔兽世界公会
比较明显的标签是Character和Guild,其他的就很难说了。
每个角色都有一个 Class,每个 Class 有 2-4 个专精,每个专精扮演 3 个角色(坦克、治疗师、伤害)之一。
我的测试查询是...
- 找到公会内的所有坦克"ABC"。
- 找到领域 "DEF" 上的所有德鲁伊 (Class)。
- 找到与"GHI".
同一个公会的所有角色
我的假设是 Role、Specialization、Class 和 Realm 也应该是标签,并在关系中附有细节。
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 个)的数量要少得多。
如果我们假设您的 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)
我正在学习 Neo4j,作为一个测试项目,我正在使用从 dev.battle.net.
检索到的数据为我的所有角色绘制我的魔兽世界公会比较明显的标签是Character和Guild,其他的就很难说了。 每个角色都有一个 Class,每个 Class 有 2-4 个专精,每个专精扮演 3 个角色(坦克、治疗师、伤害)之一。
我的测试查询是...
- 找到公会内的所有坦克"ABC"。
- 找到领域 "DEF" 上的所有德鲁伊 (Class)。
- 找到与"GHI". 同一个公会的所有角色
我的假设是 Role、Specialization、Class 和 Realm 也应该是标签,并在关系中附有细节。
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 个)的数量要少得多。
如果我们假设您的 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)