即使使用索引排序参数,MongoDB也会聚合,查询速度慢

时间:2018-01-26 15:34:19

标签: mongodb performance sorting aggregation-framework

我有以下查询:

db.Visitor.aggregate([
  {"$sort":{"updatedAt":-1}},
  {"$match":{
    "$and":[
      {"events.platformId":"8"},
      {"events.applicationId":{"$in":["354","325","373","177","379","417","415","416"]}},
      {"events.date":{"$gte":ISODate("2018-01-26 15:23:00")}},
      {"events.date":{"$lte":ISODate("2018-01-26 23:59:59")}}
    ]
  }},
  {"$project":{
    "events":{
      "$filter":{
        "input":"$events",
        "as":"event",
        "cond":{
          "$and":[
            {"$eq":["$$event.platformId","8"]},
            {"$in":["$$event.applicationId",["354","325","373","177","379","417","415","416"]]},
            {"$gte":["$$event.date",ISODate("2018-01-26 15:23:00")]},
            {"$lte":["$$event.date",ISODate("2018-01-26 23:59:59")]}
          ]
        }
      }
    }
  }},
  {"$limit":15},
], {"maxTimeMS": 2500}).pretty()

它失败,因为它达到最大执行时间。如果我把它排除在外,它会以毫秒为单位返回。

我认为它可能是一个索引问题,但它已经存在:

    {
            "v" : 1,
            "key" : {
                    "updatedAt" : -1
            },
            "name" : "expiration_ttl",
            "ns" : "analytics.Visitor",
            "expireAfterSeconds" : NumberLong(1296000)
    }

你有任何线索吗?

谢谢:)

编辑: 经过一个周末的思考后,我提出了在$sort$match之间创建一个步骤的想法,创建了一个额外的$match过滤集合中{{1}的文档在updatedAtevents.date(前requests.date)中指定的范围内。通过这种方式,查询将不会花费大量时间,因为结果集合比原始集合小得多,即使没有每个匹配条件属性的索引也能使匹配工作。

1 个答案:

答案 0 :(得分:0)

$sort阶段移至$limit之前的末尾。它应该触发sort-limit coalescence

db.Visitor.aggregate([
  {"$match":{
    ...
  }},
  {"$project":{
    "events":{
      ...
    },
    "updatedAt": 1
  }},
  {"$sort":{"updatedAt":-1}},
  {"$limit":15},
], {"maxTimeMS": 2500}).pretty()

使用hint选项使用不同的索引对其进行基准测试:

db.Visitor.aggregate(
    [...], 
    {"maxTimeMS": 2500, hint: "expiration_ttl"}
).pretty()