Mongo错误地对数组字段排序?

时间:2018-08-06 15:58:17

标签: mongodb mongodb-query

我正在尝试过滤一个不幸无法正常工作的数组字段。我读过的所有内容都表明这应该可行,并且排序正在完成某事,只是不符合我的预期,我无法解释。

我想要实现的是对数组子字段进行排序。我已经设法使用位置运算符实现了大多数功能,但是我无法弄清排序的作用。

db.getCollection('boards')
  .find({ "lastVisited.user": "AAA" }, { name: 1, "lastVisited.$" : 1 })
  .sort({ "lastVisited.0.timestamp": 1 });

这将导致以下输出

/* 1 */
{
    "_id" : ObjectId("5b642d2cac2f544b1d48d09a"),
    "lastVisited" : [ 
        {
            "user" : "AAA",
            "timestamp" : ISODate("2018-08-18T00:00:00.000Z")
        }
    ]
}

/* 2 */
{
    "_id" : ObjectId("5b6845245e102f3844d2181b"),
    "lastVisited" : [ 
        {
            "user" : "AAA",
            "timestamp" : ISODate("2018-08-16T00:00:00.000Z")
        }
    ]
}

/* 3 */
{
    "_id" : ObjectId("5b6842095e102f3844d2181a"),
    "lastVisited" : [ 
        {
            "user" : "AAA",
            "timestamp" : ISODate("2018-08-19T00:00:00.000Z")
        }
    ]
}

此处要注意的是,日期先后依次排列18th19th16th,这毫无意义!谁能解释一下?

这些是我使用过的文档:

/* 1 */
{
    "_id" : ObjectId("5b642d2cac2f544b1d48d09a"),
    "lastVisited" : [ 
        {
            "user" : "BBB",
            "timestamp" : ISODate("2018-08-04T00:00:00.000Z")
        }, 
        {
            "user" : "AAA",
            "timestamp" : ISODate("2018-08-18T00:00:00.000Z")
        }
    ]
}

/* 2 */
{
    "_id" : ObjectId("5b6842095e102f3844d2181a"),
    "lastVisited" : [ 
        {
            "user" : "AAA",
            "timestamp" : ISODate("2018-08-19T00:00:00.000Z")
        }
    ]
}

/* 3 */
{
    "_id" : ObjectId("5b6845245e102f3844d2181b"),
    "lastVisited" : [ 
        {
            "user" : "AAA",
            "timestamp" : ISODate("2018-08-16T00:00:00.000Z")
        }
    ]
}

1 个答案:

答案 0 :(得分:1)

不幸的是,您目前无法在Mongo中执行此操作,因为它仍然使用完整文档(而不仅仅是投影部分)进行排序。因此,您将需要使用聚合框架。查看未解决的问题https://jira.mongodb.org/browse/SERVER-4451

以下是聚合示例,因为您希望对匹配的元素进行排序

db.getCollection('stack1').aggregate([
// Initial document match (uses index, if a suitable one is available)
{ $match: 
    { "lastVisited.user": "AAA" }
},
{ "$unwind":"$lastVisited"},
{ $match:{
    "lastVisited.user": "AAA"
}},
{ "$sort": { "lastVisited.timestamp": 1 } }    

])