$ exists和$ in / nin计数作为非前缀排序的相等查询?

时间:2015-07-12 15:38:56

标签: mongodb mongodb-indexes

http://docs.mongodb.org/manual/tutorial/sort-results-with-indexes/#sort-and-non-prefix-subset-of-an-index

索引

{ a: 1, b: 1, c: 1}

支持此查询:

db.data.find( { b: 3, a: 4 } ).sort( { c: 1 } )

是否也支持

db.data.find( { b: 3, a: {$exists: true} } ).sort( { c: 1 } )
db.data.find( { b: {$in: [3,4]}, a: 4 } ).sort( { c: 1 } )
db.data.find( { b: {$nin: [3,4]}, a: {$exists: false} } ).sort( { c: 1 } )

1 个答案:

答案 0 :(得分:1)

所有查询都将使用索引进行检索,但仅使用第2个进行排序,因为其他查询使用的运算符不是相等条件。

您可以通过使用.explain()

运行查询来证明这一点

请参阅下面这3个查询的explain(来自MongoDB 2.6.3)的输出,省略了不必要的字段。 "cursor"显示使用的索引,"indexBounds"显示索引键的下限和上限。 "scanAndOrder" : false表示该索引也用于排序。

"indexBounds"很重要,因为您可以看到相等条件 - 例如,请注意"$exists" : false是一个相等条件(为null)并且可能会使用索引而"$exists" : true是一个范围。

另请参阅documentation on explain,这对于了解索引使用情况和诊断性能问题非常有用。

db.data.find( { b: 3, a: {$exists: true} } ).sort( { c: 1 } ).explain()
{
    "cursor" : "BtreeCursor a_1_b_1_c_1",
    "scanAndOrder" : true,
    "indexBounds" : {
        "a" : [
            [
                {
                    "$minElement" : 1
                },
                {
                    "$maxElement" : 1
                }
            ]
        ],
        "b" : [
            [
                3,
                3
            ]
        ],
        "c" : [
            [
                {
                    "$minElement" : 1
                },
                {
                    "$maxElement" : 1
                }
            ]
        ]
    },
}

db.data.find( { b: {$in: [3,4]}, a: 4 } ).sort( { c: 1 } ).explain()
{
    "clauses" : [
        {
            "cursor" : "BtreeCursor a_1_b_1_c_1",
            "scanAndOrder" : false,
            "indexBounds" : {
                "a" : [
                    [
                        4,
                        4
                    ]
                ],
                "b" : [
                    [
                        3,
                        3
                    ]
                ],
                "c" : [
                    [
                        {
                            "$minElement" : 1
                        },
                        {
                            "$maxElement" : 1
                        }
                    ]
                ]
            }
        },
        {
            "cursor" : "BtreeCursor a_1_b_1_c_1",
            "scanAndOrder" : false,
            "indexBounds" : {
                "a" : [
                    [
                        4,
                        4
                    ]
                ],
                "b" : [
                    [
                        4,
                        4
                    ]
                ],
                "c" : [
                    [
                        {
                            "$minElement" : 1
                        },
                        {
                            "$maxElement" : 1
                        }
                    ]
                ]
            }
        }
    ],
}    

db.data.find( { b: {$nin: [3,4]}, a: {$exists: false} } ).sort( { c: 1 } ).explain()
{
    "cursor" : "BtreeCursor a_1_b_1_c_1",
    "scanAndOrder" : true,        
    "indexBounds" : {
        "a" : [
            [
                null,
                null
            ]
        ],
        "b" : [
            [
                {
                    "$minElement" : 1
                },
                3
            ],
            [
                3,
                4
            ],
            [
                4,
                {
                    "$maxElement" : 1
                }
            ]
        ],
        "c" : [
            [
                {
                    "$minElement" : 1
                },
                {
                    "$maxElement" : 1
                }
            ]
        ]
    },
}