2

我想建立一个索引,支持针对特定数组元素位置的查询。

给定数百万个包含值数组的文档:

db.foo.insert({ array: [true, false, null, true] })
db.foo.insert({ array: [false, null, true, true] })

我想搜索true位置为 2 的文档。

db.foo.find({ "array.2": true })

如果我创建一个多键索引:

db.foo.createIndex({ array: 1 })

索引支持形式的查询{ "array": true }(搜索所有数组元素)但不支持{ "array.2": true }(搜索特定数组元素)。

文档说“ MongoDB 为数组中的每个元素创建一个索引键”,所以我期待如果我在该array字段上创建一个索引,它将用于查询array.0, array.1,array.2等。有没有一个技巧来获得这个去工作?

4

1 回答 1

3

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 运算符来确保整个子文档匹配。假设您正在搜索kof 2 和vof 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在做之前知道最大值。$pushk

于 2018-03-08T06:28:04.577 回答