Mongo聚合结合了$ match步骤,导致查询速度慢

时间:2014-10-14 02:38:56

标签: mongodb

这个问题是Query with $in and $nin doesn't use index的后续问题。我已经尝试使用聚合来声明步骤的顺序。

db.assets.aggregate([
  {
    "$match": {
      "tags": {
        "$in": ["blah"]
      }
    }
  },
  {
    "$match": {
      "tags": {
        "$nin": ["test"]
      }
    }
  }
], {"explain": true})

你认为Mongo现在明白我们想先用$过滤。好吧,你会感到惊讶。

{
  "stages" : [
    {
      "$cursor" : {
        "query" : {
          "$and" : [
            {
              "tags" : {
                "$in" : [
                  "blah"
                ]
              }
            },
            {
              "tags" : {
                "$nin" : [
                  "test"
                ]
              }
            }
          ]
        },
        "planError" : "InternalError No plan available to provide stats"
      }
    }
  ],
  "ok" : 1
}

规划师甚至不知道该怎么做。事实证明它实际上将$match es组合成一个查询,然后遇到与Query with $in and $nin doesn't use index相同的问题,最终在大约2-3秒内返回结果(对应于链接上的2331ms)问题)。

1 个答案:

答案 0 :(得分:0)

看起来你可以通过插入一个空的跳过步骤来欺骗聚合器:

db.assets.aggregate([
  {
    "$match": {
      "tags": {
        "$in": ["blah"]
      }
    }
  },
  {
    "$skip": 0
  },
  {
    "$match": {
      "tags": {
        "$nin": ["test"]
      }
    }
  }
], {"explain": true})

这样,计划者将使用索引并立即返回结果。

{
  "stages" : [
    {
      "$cursor" : {
        "query" : {
          "tags" : {
            "$in" : [
              "blah"
            ]
          }
        },
        "plan" : {
          "cursor" : "BtreeCursor ",
          "isMultiKey" : false,
          "scanAndOrder" : false,
          "indexBounds" : {
            "tags" : [
              [ "blah", "blah" ]
            ]
          },
          "allPlans" : [
            {
              "cursor" : "BtreeCursor ",
              "isMultiKey" : false,
              "scanAndOrder" : false,
              "indexBounds" : {
                "tags" : [
                  [ "blah", "blah" ]
                ]
              }
            }
          ]
        }
      }
    },
    {
      "$skip" : NumberLong(0)
    },
    {
      "$match" : {
        "tags" : {
          "$nin" : [
            "test"
          ]
        }
      }
    }
  ],
  "ok" : 1
}