ArangoDB 索引和数组

ArangoDB Indexes and arrays

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

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

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

  2. 为"contacts[].items[].value"

    创建哈希索引

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

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

大约 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", {});

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

  1. 获取所有管理员:

    RETURN 邻居(群组,isInGroup,"admin")

  2. 获取联系人值为333444222的所有用户:

    FOR x IN contacts FILTER x.value == "333444222" RETURN NEIGHBORS(contacts, hasContact, x)

索引可以从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 不行。