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' }
]
}
]
...
}
为"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
结果:不支持通配符的双重使用??未使用索引,查询为空
问题:如何为这个带索引的结构组织快速查找?
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", {});
现在您可以执行以下查询:
获取所有管理员:
RETURN 邻居(群组,isInGroup,"admin")
获取联系人值为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
不行。
我正在尝试使用文档集合进行快速查找,示例文档 文档人 {
...
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
结果:不支持通配符的双重使用??未使用索引,查询为空 问题:如何为这个带索引的结构组织快速查找?
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", {});
现在您可以执行以下查询:
获取所有管理员:
RETURN 邻居(群组,isInGroup,"admin")
获取联系人值为
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
不行。