基于日期范围的查询在Mongo CLI和Casbah上表现不同

时间:2017-08-30 09:41:46

标签: mongodb casbah

以下查询适用于Mongo CLI,但不适用于Casbah API。

查询:

db.collection.aggregate([
    {$unwind:'$views'},
    {$project:{'views': 1}},
    {$match:{'views.date':{$gte: ISODate('2017-06-01T00:00:00.000Z'), $lt: ISODate('2017-06-02T00:00:00.000Z')}}}
])

该查询适用于Mongo CLI,并在几秒钟内返回相关结果。以下是Mongo CLI提供的执行计划:

{
    "stages": [{
        "$cursor": {
            "query": {},
            "fields": {
                "views": 1,
                "_id": 1
            },
            "queryPlanner": {
                "plannerVersion": 1,
                "namespace": "database.collection",
                "indexFilterSet": false,
                "parsedQuery": {
                    "$and": []
                },
                "winningPlan": {
                    "stage": "COLLSCAN",
                    "filter": {
                        "$and": []
                    },
                    "direction": "forward"
                },
                "rejectedPlans": []
            }
        }
    },
    {
        "$unwind": "$views"
    },
    {
        "$project": {
            "views": true
        }
    },
    {
        "$match": {
            "views.date": {
                "$gte": ISODate("2017-06-01T00:00:00Z"),
                "$lt": ISODate("2017-06-02T00:00:00Z")
            }
        }
    }],
    "ok": 1
}

当我使用Cashbah执行查询时,我在4分钟后收到以下错误:

Command failed with error 16389: 'exception: aggregation result exceeds maximum document size (16MB)' on server ip:port.

这是使用Casbah 3.1.1的scala代码:

val client = MongoClient(host, port)
val database = client(databaseName)
val coll = database(collectionName)

val explode = BasicDBObject.parse("{$unwind:'$views'}")
val projection = BasicDBObject.parse("{$project:{'views': 1}}")
val query = BasicDBObject.parse("{$match:{'views.date':{$gte: ISODate('2017-06-01T00:00:00.000Z'), $lt: ISODate('2017-06-02T00:00:00.000Z')}}}")
coll.aggregate(Seq(explode, projection, query)).results

以下是Cashbah提供的执行计划:

{
    [{
        "$cursor": {
            "query": {},
            "fields": {
                "views": 1,
                "_id": 1
            },
            "queryPlanner": {
                "plannerVersion": 1,
                "namespace": "kimono.real_estate_ads",
                "indexFilterSet": false,
                "parsedQuery": {
                    "$and": []
                },
                "winningPlan": {
                    "stage": "COLLSCAN",
                    "filter": {
                        "$and": []
                    },
                    "direction": "forward"
                },
                "rejectedPlans": []
            }
        }
    },
    {
        "$unwind": "$views"
    },
    {
        "$project": {
            "views": true
        }
    },
    {
        "$match": {
            "views.date": {
                "$gte": {
                    "$date": "2017-06-01T12:00:00.000Z"
                },
                "$lt": {
                    "$date": "2017-06-02T00:00:00.000Z"
                }
            }
        }
    }],
    "ok": 1
}

两个执行计划之间的唯一区别是如何表示日期:

    使用Mongo CLI时
  • ISODate(" 2017-06-01T00:00:00Z")
  • " $ date":" 2017-06-02T00:00:00.000Z"使用Casbah时

我尝试过的事情:

  • 更改管道中元素的顺序:显示的顺序是在Mongo CLI上提供最佳执行时间的顺序;其他可能性在Casbah上返回相同的错误
  • ISODate(...)替换为new ISODate(...){$date:'...'}{'$date':'...'}{"$date":"..."}:没有区别

同一个集合中还有其他数组具有与查询相似的结构。

感谢任何帮助。

0 个答案:

没有答案