首页 文章

ArangoDB索引和数组

提问于
浏览
2

我正在尝试使用文档集合进行快速查找,示例文档文档Person {

...
groups: ["admin", "user", "godmode"],
contacts: [
   {
     label: "main office",
     items: [
        { type: "phone", value: '333444222' },
        { type: "phone", value: '555222555' },
        { type: "email", value: 'bob@gmail.com' }
     ]
   }
]
...
}
  • 为“groups”字段创建哈希索引

查询: For P in Person FILTER "admin" IN P.groups RETURN P 结果:工作,但没有通过解释查询使用索引问题:如何使用数组过滤和索引查询?表现是主要因素

  • 为“contacts [] . items [] . value”创建哈希索引

查询: For P in Person FILTER "333444222" == P.contacts[*].items[*].value RETURN P 结果:不支持双重使用通配符?索引未使用,查询为空问题:如何使用索引组织快速查找此结构?

附:还尝试了MATCHES函数,多杠杆for-in,哈希索引的数组从未使用ArangoDB版本2.6.8

2 回答

  • 3

    关于1.)这是正在进行的工作,将包含在下一个版本中(最有可能是2.8) . 我们尚未决定使用AQL语法来检索数组,但 FILTER "admin" IN P.groups 是最可能的 .

    关于2.)已经实现1.这也将开箱即用,索引将能够覆盖几个嵌套深度 .

    在当前版本中,上述任何一种都不能正确编入索引(2.6)

    我可以提供的唯一选择是外部化值并使用边而不是数组 . 在您的代码中,数据将如下(在arangosh中) . 为简单起见,我使用了固定的 _key 值,没有它们也可以使用:

    db._create("groups"); // saves the group elements
    db._create("contacts"); // saves the contact elements
    db._ensureHashIndex("value") // Index on contacts.value
    db._create("Person"); // You already have this
    db._createEdgeCollection("isInGroup"); // Save relation group -> person
    db._createEdgeCollection("hasContact"); // Save relation item -> person
    db.Person.save({_key: "user"}) // The remainder of the object you posted
    // Now the items
    db.contacts.save({_key:"phone1", type: "phone", value: '333444222' });
    db.contacts.save({_key:"phone2", type: "phone", value: '555222555' });
    db.contacts.save({_key:"mail1", type: "email", value: 'bob@gmail.com'});
    // And the groups
    db.groups.save({_key:"admin"});
    db.groups.save({_key:"user"});
    db.groups.save({_key:"godmode"});
    
    // Finally the relations
    db.hasContact.save({"contacts/phone1", "Person/user", {label: "main office"});
    db.hasContact.save({"contacts/phone2", "Person/user", {label: "main office"});
    db.hasContact.save({"contacts/mail1", "Person/user", {label: "main office"});
    db.isInGroup.save("groups/admin", "Person/user", {});
    db.isInGroup.save("groups/godmode", "Person/user", {});
    db.isInGroup.save("groups/user", "Person/user", {});
    

    现在您可以执行以下查询:

    • 获取所有管理员:

    返回邻居(groups,isInGroup,“admin”)

    • 获取具有值为 333444222 的联系人的所有用户:

    FOR x IN联系人FILTER x.value ==“333444222”RETURN NEIGHBORS(contacts,hasContact,x)

  • 2

    索引可以在ArangoDB版本2.8上使用 . 对于第一个查询( FILTER "admin" IN p.groups ),字段 groups[*] 上的数组哈希索引将起作用:

    db._create("persons");
    db.persons.insert(personDateFromOriginalExample);
    db.persons.ensureIndex({ type: "hash", fields: [ "groups[*]" ] });
    

    2.8之前的版本中不存在此类索引 . 使用数组索引,查询将生成以下执行计划(显示实际使用了索引):

    Execution plan:
     Id   NodeType          Est.   Comment
      1   SingletonNode        1   * ROOT
      6   IndexNode            1     - FOR p IN persons   /* hash index scan */
      3   CalculationNode      1       - LET #1 = "admin" in p.`groups`   /* simple expression */   /* collections used: p : persons */
      4   FilterNode           1       - FILTER #1
      5   ReturnNode           1       - RETURN p
    
    Indexes used:
     By   Type   Collection   Unique   Sparse   Selectivity   Fields            Ranges
      6   hash   persons      false    false       100.00 %   [ `groups[*]` ]   "admin" in p.`groups`
    

    数组索引不支持第二个查询,因为它包含多个嵌套级别 . 2.8中的数组索引限制在一个级别,例如 groups[*]contacts[*].label 将起作用,但不是 groups[*].items[*].value .

相关问题