代码之家  ›  专栏  ›  技术社区  ›  charles082986

Neo4j标签与节点属性

  •  2
  • charles082986  · 技术社区  · 7 年前

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

    最明显的标签是角色和公会,但其他一些很难分辨。 每个角色都有一个职业,每个职业有2-4个专长,每个专长填充3个角色中的一个(坦克、治疗者、伤害)。

    我的测试查询是。。。

    • 查找帮会“ABC”中的所有坦克。
    • 在“DEF”领域找到所有德鲁伊(职业)。
    • 查找与“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 回复  |  直到 7 年前
        1
  •  3
  •   cybersam    7 年前

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

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

    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)