索引 MongoDB 数组位置查询
Indexing MongoDB array position queries
我想建立一个支持查询特定数组元素位置的索引。
给定数百万个包含值数组的文档:
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 creates an index key for each element in the array",所以我希望如果我在 array
字段上创建索引,它将用于 array.0
上的查询, array.1
、array.2
等。有什么技巧可以让它发挥作用吗?
MongoDB的多键索引只索引数组的值,而不索引所述值在数组中的位置。
话虽如此,有一种可能的解决方法可以满足您的要求。
您需要存储显示元素位置的 "key" 而不是仅存储数组的值。使用您的示例:
> 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}
]
}
请注意,在上面的示例中,我使用 sub-documents 和字段 k
表示 "array position",字段 v
存储 "array element".
然后您可以创建索引这两个字段的索引:
db.test.createIndex({'a.k':1, 'a.v':1})
并且查询应该使用$elemMatch operator来确保整个sub-document匹配。假设您正在搜索 k
of 2 和 v
of true
:
> 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
的最大值。
我想建立一个支持查询特定数组元素位置的索引。
给定数百万个包含值数组的文档:
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 creates an index key for each element in the array",所以我希望如果我在 array
字段上创建索引,它将用于 array.0
上的查询, array.1
、array.2
等。有什么技巧可以让它发挥作用吗?
MongoDB的多键索引只索引数组的值,而不索引所述值在数组中的位置。
话虽如此,有一种可能的解决方法可以满足您的要求。
您需要存储显示元素位置的 "key" 而不是仅存储数组的值。使用您的示例:
> 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}
]
}
请注意,在上面的示例中,我使用 sub-documents 和字段 k
表示 "array position",字段 v
存储 "array element".
然后您可以创建索引这两个字段的索引:
db.test.createIndex({'a.k':1, 'a.v':1})
并且查询应该使用$elemMatch operator来确保整个sub-document匹配。假设您正在搜索 k
of 2 和 v
of true
:
> 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
的最大值。