强制使用索引复杂的MongoDB查询?

时间:2014-02-08 16:52:13

标签: mongodb

我有一大堆带有“to”,“from”,“type”和“visible_to”字段的“消息”,我想通过一个相当复杂的查询来查询这些字段,这些查询只会将消息传入/传出该用户可见的特定类型集的特定用户。这是一个实际的例子:

{
  "$and": [
    {
      "$and": [
        {
          "$or": [
            {
              "to": "52f65f592f1d88ebcb00004f"
            },
            {
              "from": "52f65f592f1d88ebcb00004f"
            }
          ]
        },
        {
          "$or": [
            {
              "type": "command"
            },
            {
              "type": "image"
            }
          ]
        }
      ]
    },
    {
      "$or": [
        {
          "public": true
        },
        {
          "visible_to": "52f65f592f1d88ebcb00004f"
        }
      ]
    }
  ]
}

使用索引:

[
    {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "ns" : "n2-mongodb.messages",
        "name" : "_id_"
    },
    {
        "v" : 1,
        "key" : {
            "expires" : 1
        },
        "ns" : "n2-mongodb.messages",
        "name" : "expires_1",
        "background" : true,
        "safe" : null
    },
    {
        "v" : 1,
        "key" : {
            "from" : 1
        },
        "ns" : "n2-mongodb.messages",
        "name" : "from_1",
        "background" : true,
        "safe" : null
    },
    {
        "v" : 1,
        "key" : {
            "type" : 1
        },
        "ns" : "n2-mongodb.messages",
        "name" : "type_1",
        "background" : true,
        "safe" : null
    },
    {
        "v" : 1,
        "key" : {
            "ts" : 1,
            "type" : -1
        },
        "ns" : "n2-mongodb.messages",
        "name" : "ts_1_type_-1",
        "background" : true,
        "safe" : null
    },
    {
        "v" : 1,
        "key" : {
            "to" : 1
        },
        "ns" : "n2-mongodb.messages",
        "name" : "to_1",
        "background" : true,
        "safe" : null
    },
    {
        "v" : 1,
        "key" : {
            "visible_to" : 1
        },
        "ns" : "n2-mongodb.messages",
        "name" : "visible_to_1",
        "background" : true,
        "safe" : null
    },
    {
        "v" : 1,
        "key" : {
            "public" : 1,
            "visible_to" : 1
        },
        "ns" : "n2-mongodb.messages",
        "name" : "public_1_visible_to_1"
    },
    {
        "v" : 1,
        "key" : {
            "to" : 1,
            "from" : 1
        },
        "ns" : "n2-mongodb.messages",
        "name" : "to_1_from_1"
    }
]

这是MongoDB 2.2.2实例的解释(true)输出,看起来像是一个完整的扫描:

{
    "cursor" : "BasicCursor",
    "isMultiKey" : false,
    "n" : 0,
    "nscannedObjects" : 35702,
    "nscanned" : 35702,
    "nscannedObjectsAllPlans" : 35702,
    "nscannedAllPlans" : 35702,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 1,
    "nChunkSkips" : 0,
    "millis" : 85,
    "indexBounds" : {

    },
    "allPlans" : [
        {
            "cursor" : "BasicCursor",
            "n" : 0,
            "nscannedObjects" : 35702,
            "nscanned" : 35702,
            "indexBounds" : {

            }
        }
    ],
    "server" : "XXXXXXXX"
}

查看解释输出,MongoDB没有使用任何索引 - 有没有办法让它至少使用复合索引{to:1,from:1}来大大缩小搜索空间?或者有更好的方法来优化此查询吗?或者MongoDB完全不适合这样的查询?

2 个答案:

答案 0 :(得分:0)

要强制MongoDB查询优化器采用特定方法,您可以使用$hint运算符。 来自文档,

The $hint operator forces the query optimizer to use a specific index to fulfill the query.      Specify the index either by the index name or by document.

答案 1 :(得分:0)

MongoDB 2.6中的查询优化器将支持将索引应用于复杂查询。