mongodb - MongoDB 如何处理嵌套在数组中的对象属性的复合索引?

标签 mongodb

我明白 Compound Multikey Indexes May Only Include One Array Field .

以下不会产生“无法索引并行数组”错误:

db.test.ensureIndex({"values.x": 1, "values.y": 1})

db.test.insert({"values": [ {"x": 1, "y": 2}, {"x": 2, "y": 2} ]})
db.test.insert({"values": [ {"x": 2, "y": 1}, {"x": 1, "y": 1} ]})
db.test.insert({"values": [ {"x": 1, "y": 1}, {"x": 1, "y": 1} ]})

因此,复合索引似乎允许用于多个对象属性,其中对象嵌套在一个数组字段中。

文档说“MongoDB 分别为数组中的每个值编制索引”,因此对于上述情况,我希望在每个文档中创建 values.x 和 values.y 的所有组合的索引条目。

然而,以下对两个嵌套字段的查询表明仅使用复合索引中的第一个字段 - nscanned 为 2,表明 Mongo 必须检查第二个添加的文档以检查数组元素上的 y = 2匹配 x = 2。

db.test.find({"values.x": 2, "values.y": 2}).explain()
{
    "cursor" : "BtreeCursor values.x_1_values.y_1",
    "isMultiKey" : true,
    "n" : 1,
    "nscannedObjects" : 2,
    "nscanned" : 2,
    "nscannedObjectsAllPlans" : 2,
    "nscannedAllPlans" : 2,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "millis" : 0,
    "indexBounds" : {
            "values.x" : [
                    [
                            2,
                            2
                    ]
            ],
            "values.y" : [
                    [
                            {
                                    "$minElement" : 1
                            },
                            {
                                    "$maxElement" : 1
                            }
                    ]
            ]
    },
    "server" : "localhost:27017"
}

MongoDB 的索引是什么,复合索引比只覆盖第一个字段的索引有什么值(value)吗?

最佳答案

如果您使用 $elemMatch查询运算符在同一元素中搜索 xy 值,您会看到索引范围也适用于 y:

> db.test.find({ values: { $elemMatch: { x: 2, y: 2 }}}).explain()
{
    "cursor" : "BtreeCursor values.x_1_values.y_1",
    "isMultiKey" : true,
    "n" : 1,
    "nscannedObjects" : 1,
    "nscanned" : 1,
    "nscannedObjectsAllPlans" : 1,
    "nscannedAllPlans" : 1,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "millis" : 0,
    "indexBounds" : {
        "values.x" : [
            [
                2,
                2
            ]
        ],
        "values.y" : [
            [
                2,
                2
            ]
        ]
    },
    "server" : "localhost:27017"
}

这是在 SERVER-3104 中为 2.4 实现的.票证说明解释了为什么这些索引范围不能用于您的原始查询:

Mongo does not compute a cartesian product when creating a compound index on multiple fields. If the document { a:[ { b:1, c:2 }, { b:10, c:20 } ] } is indexed according to index { 'a.b':1, 'a.c':1 }, the index keys created are { '':1, '':2 } and { '':10, '':20 }. (There is no index key { '':1, '':20 } for example.)

Now, suppose we have a query { 'a.b':1, 'a.c':20 }. This query is supposed to match the document, because an 'a.b' value of 1 exists in the document, and an 'a.c' value of 20 exists in the document. However, there is no index key containing both 1 in the 'a.b' position and 20 in the 'a.c' position. As a result, the index bounds on 'a.b' will be [[ 1, 1 ]] but there will not be any index bounds on 'a.c'. This means the index key { '':1, '':2 } will be retrieved and used to find the full document, and the Matcher will determine that the full document matches the query

关于mongodb - MongoDB 如何处理嵌套在数组中的对象属性的复合索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14894714/

相关文章:

javascript - Mongoose 分页与排序

ruby-on-rails - MongoDB 和 Rails : How to create Index

mongodb - 蒙哥 : export all fields data from collection without specifying fields?

mongodb - 如何将 $arrayToObject 应用于 mongodb 聚合中 $push 输出的数组

javascript - Mongoose,保存查找结果似乎什么也没做

mongodb - mongorestore 0 文档已成功恢复。 0 个文档无法恢复

node.js - Node.js 中的响应大小是否有大小限制

javascript - 如何在node.js中导出多个mongoose模型模块

mongodb - Rocketchat 连接以保护 MongoDB

c# - 为什么我的记录在 mongodb upsert 场景中得到零 objectid?