1

I have this kind of simple aggregate query

db.SomeCollection.aggregate([{
  "$match": {
    "Id": "someId"
  }
}, {
  "$sort": {
    "someISODatePropertyName": 1
  }
}, {
  "$unwind": {
    "path": "$somePropertyName"
  }
}], {
  allowDiskUse: true
})

this query returns 50 items at most and takes 10 seconds to complete.

If I simply change the sort property with a numeric one:

db.SomeCollection.aggregate([{
  "$match": {
    "Id": "someId"
  }
}, {
  "$sort": {
    "someNumericPropertyName": 1
  }
}, {
  "$unwind": {
    "path": "$somePropertyName"
  }
}], {
  allowDiskUse: true
})

the query takes a few milliseconds to complete.

Is there any sorting issue with ISODate properties?

I really can't understand why it takes so long in the first version.

Thank you.

UPDATE

this is the query result with "explain" flag set to true (note: on the ISODate field there is an index):

{
    "waitedMS" : NumberLong(0),
    "stages" : [ 
        {
            "$cursor" : {
                "query" : {
                    "StreamId" : "5b8cc895-c626-5994-95d4-b9ac89fb66ed"
                },
                "sort" : {
                    "CommitStamp" : 1
                },
                "queryPlanner" : {
                    "plannerVersion" : 1,
                    "namespace" : "vrp-events-prod.Commits",
                    "indexFilterSet" : false,
                    "parsedQuery" : {
                        "StreamId" : {
                            "$eq" : "5b8cc895-c626-5994-95d4-b9ac89fb66ed"
                        }
                    },
                    "winningPlan" : {
                        "stage" : "FETCH",
                        "filter" : {
                            "StreamId" : {
                                "$eq" : "5b8cc895-c626-5994-95d4-b9ac89fb66ed"
                            }
                        },
                        "inputStage" : {
                            "stage" : "IXSCAN",
                            "keyPattern" : {
                                "CommitStamp" : 1
                            },
                            "indexName" : "CommitStamp_Index",
                            "isMultiKey" : false,
                            "isUnique" : false,
                            "isSparse" : false,
                            "isPartial" : false,
                            "indexVersion" : 1,
                            "direction" : "forward",
                            "indexBounds" : {
                                "CommitStamp" : [ 
                                    "[MinKey, MaxKey]"
                                ]
                            }
                        }
                    },
                    "rejectedPlans" : []
                }
            }
        }, 
        {
            "$unwind" : {
                "path" : "$Events"
            }
        }
    ],
    "ok" : 1
}
4

1 回答 1

0

以我的经验,在日期字段上没有索引的日期排序很慢。假设您经常从这个集合中读取数据并且通常按日期排序,那么添加索引将是理想的解决方案。

db.collection.createIndex("someISODatePropertyName": 1 or -1)

试试吧,它总是对我产生巨大的影响。

更新:

假设这不会过多地减慢您的写入查询,请添加一个涵盖匹配和排序的索引:

db.xxx.createIndex({"StreamId": 1, "CommitStamp": 1});

我在我的集​​合上对此进行了测试,它将查询从 15 秒(使用日期索引)加速到不到一秒(使用新创建的索引)。仅供参考,我更新的解释显示:

"queryPlanner" : {
                                        "plannerVersion" : 1,
                                        "namespace" : "db.xxx",
                                        "indexFilterSet" : false,
                                        "parsedQuery" : {
                                                "id" : {
                                                        "$eq" : 122
                                                }
                                        },
                                        "winningPlan" : {
                                                "stage" : "FETCH",
                                                "inputStage" : {
                                                        "stage" : "IXSCAN",
                                                        "keyPattern" : {
                                                                "id" : 1,
                                                                "date" : 1
                                                        },
                                                        "indexName" : "id_1_date_1",
                                                        "isMultiKey" : false,
                                                        "direction" : "forward",
                                                        "indexBounds" : {
                                                                "id" : [
                                                                        "[122.0, 122.0]"
                                                                ],
                                                                "date" : [
                                                                        "[MinKey, MaxKey]"
                                                                ]
                                                        }
                                                }
                                        },
                                        "rejectedPlans" : [ ]
                                }
于 2016-05-19T15:08:59.907 回答