Mongodb复合索引和排序

时间:2015-01-30 17:18:56

标签: mongodb indexing

我有这个系列:

db.place.find() : 
    {
    _id : "p1",
    alterNames : ["abcd","abcD"],
    population : 122
    }
    {
    _id : "p2",
    alterNames : ["qsdf","qsDF"],
    population : 100
    }

我想找到以“ab”开头的 alterNames 的文档,并按人口对其进行排序。 我创建了索引{alterNames : 1, population : -1}

我的查询:

db.place.find({alterNames : /^ab/}).sort({population : -1}).limit(10).explain()

我等着看"n" = "nScannedObjects" = 10 我得到了什么:

"n" = 10
"nScannedObjects" = 4765

我错过了什么吗?

编辑: 以下是完整的解释:

db.place.find({alterNames : /^pari/ }).sort({population : -1}).limit(10).explain()

      "clauses" : [
              {
                      "cursor" : "BtreeCursor alterNames_1_population_-1",
                      "isMultiKey" : true,
                      "n" : 10,
                      "nscannedObjects" : 4765,
                      "nscanned" : 4883,
                      "scanAndOrder" : true,
                      "indexOnly" : false,
                      "nChunkSkips" : 0,
                      "indexBounds" : {
                              "alterNames" : [
                                      [
                                              "pari",
                                              "parj"
                                      ],
                                      [
                                              /^pari/,
                                              /^pari/
                                      ]
                              ],
                              "population" : [
                                      [
                                              {
                                                      "$maxElement" : 1
                                              },
                                              {
                                                      "$minElement" : 1
                                              }
                                      ]
                              ]
                      }
              },
              {
                      "cursor" : "BtreeCursor ",
                      "isMultiKey" : false,
                      "n" : 0,
                      "nscannedObjects" : 0,
                      "nscanned" : 0,
                      "scanAndOrder" : true,
                      "indexOnly" : false,
                      "nChunkSkips" : 0,
                      "indexBounds" : {
                              "alterNames" : [
                                      [
                                              "pari",
                                              "parj"
                                      ],
                                      [
                                              /^pari/,
                                              /^pari/
                                      ]
                              ],
                              "population" : [
                                      [
                                              {
                                                      "$maxElement" : 1
                                              },
                                              {
                                                      "$minElement" : 1
                                              }
                                      ]
                              ]
                      }
              }
      ],
      "cursor" : "QueryOptimizerCursor",
      "n" : 10,
      "nscannedObjects" : 4765,
      "nscanned" : 4883,
      "nscannedObjectsAllPlans" : 4765,
      "nscannedAllPlans" : 4883,
      "scanAndOrder" : false,
      "nYields" : 890,
      "nChunkSkips" : 0,
      "millis" : 396,
      "server" : "localhost:27017",
      "filterSet" : false

1 个答案:

答案 0 :(得分:1)

你的记谱很混乱。我假设你的集合包含的文档看起来像places数组中的两个文档。

> db.test.find()
{ "_id" : "p1", "alterNames" : [ "abcd", "abcD" ], "population" : 122 }
{ "_id" : "p2", "alterNames" : [ "qsdf", "qsDF" ], "population" : 100 }

对于像/^ab/这样的左锚定正则表达式,MongoDB将查询转换为实际上是范围查询的查询,并且可以有效地使用索引

{ "alterNames" : /^ab/ } => { "alterNames" : { "$gte" : "ab", "$lt" : "ac" } }

与范围匹配的每个值(例如"abcd")对于population(多键)值为alterNames的文档,其索引值低于"abcd"。要以population - 顺序返回匹配的文档,MongoDB必须对从每个匹配存储桶返回的文档进行外部排序。我相信这是你的更高nscannedObjects的来源。如果你查看解释(这可能很好地包含在内),你应该找到scanAndOrder : true