我想构建一个支持针对特定数组元素位置进行查询的索引。
给定数百万个包含值数组的文档:
db.foo.insert({ array: [true, false, null, true] })
db.foo.insert({ array: [false, null, true, true] })
我想搜索位置 2 为 true
的文档。
db.foo.find({ "array.2": true })
如果我创建多键索引:
db.foo.createIndex({ array: 1 })
索引支持 { "array": true }
形式的查询(搜索所有数组元素),但不支持 { "array.2": true }
(搜索特定的数组元素)。
documentation说“MongoDB为数组中的每个元素创建一个索引键”,所以我期望如果我在 array
字段上创建索引,它将用于对 array.0 的查询
、array.1
、array.2
等。有什么技巧可以让它发挥作用吗?
最佳答案
MongoDB 的多键索引仅索引数组的值,而不索引该值在数组中的位置。
话虽如此,有一种可能的解决方法可以满足您的要求。
您需要存储一个显示元素位置的“键”,而不是仅存储数组的值。使用您的示例:
> db.test.find()
{
"_id": 0,
"a": [
{"k": 0, "v": true},
{"k": 1, "v": false},
{"k": 2, "v": null},
{"k": 3, "v": true}
]
}
{
"_id": 1,
"a": [
{"k": 0, "v": false},
{"k": 1, "v": null},
{"k": 2, "v": true},
{"k": 3, "v": true}
]
}
请注意,在上面的示例中,我使用带有字段 k
的子文档来表示“数组位置”,并使用字段 v
来存储“数组元素”。
然后您可以创建一个索引来索引这两个字段:
db.test.createIndex({'a.k':1, 'a.v':1})
查询应使用 $elemMatch operator确保整个子文档匹配。假设您正在搜索 2 的 k
和 true
的 v
:
> db.test.find({a: {$elemMatch: {k:2, v:true}}})
{
"_id": 1,
"a": [
{"k": 0, "v": false},
{"k": 1, "v": null},
{"k": 2, "v": true},
{"k": 3, "v": true}
]
}
这种方法的一个缺点是您需要自己处理 k
字段。插入数组有点复杂,因为如果你想处理 k
,在执行 $push
之前你必须知道 k
的最高值> 就像数组索引一样。
关于arrays - 索引 MongoDB 数组位置查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49134851/