Mongodb聚合$ project获取数组位置元素字段值

时间:2015-10-02 00:34:08

标签: mongodb mongodb-query aggregation-framework

文件:

{
    "_id" : ObjectId("560dcd15491a065d6ab1085c"),
    "title" : "example title",
    "views" : 1,
    "messages" : [
        {
            "authorId" : ObjectId("560c24b853b558856ef193a3"),
            "authorName" : "Karl Morrison",
            "created" : ISODate("2015-10-02T00:17:25.119Z"),
            "message" : "example message"
        }
    ]
}

项目:

$project: {
    _id: 1,
    title: 1,
    views: 1,
    updated: '$messages[$messages.length-1].created' // <--- ReferenceError: $messages is not defined
}

我正在尝试从文档内部的数组中获取最后一个元素创建的值。我正在阅读documentation,但这项具体任务尚未完成。

我已经了解到它与dot notation有关。然而,并没有说明如何获得最后一个元素。

1 个答案:

答案 0 :(得分:4)

您不能只提取属性或基本上更改基本.find()查询的结果,而不仅仅是简单的顶级字段选择,因为它不受支持。对于更高级的操作,您可以使用聚合框架。

但是,即使没有触及.aggregate()$slice投影操作符也会让您大部分时间都在那里:

db.collection.find({},{ "messages": { "$slice": -1 } })

你不能改变结构,但它是最后一个没有努力的数组元素。

直到MongoDB的新版本(编写时),聚合框架仍然需要$unwind数组才能进入&#34; last&#34;元素,您可以使用$last分组累加器选择:

db.collection.aggregate([
    { "$unwind": "$messages" },
    { "$group": {
        "_id": "$_id",
        "title": { "$last": "$title" },
        "views": { "$last": "$views" },
        "created": { "$last": "$messages.created" }
   }}
])

未来版本在聚合中有$slice$arrayElemAt,可以直接处理。但是您还需要设置一个带$let的变量来处理点标记字段:

    [
        { "$project": {
            "name": 1,
            "views": 1,
            "created": {
                "$let": {
                    "vars": {
                        "message": { 
                            "$arrayElemAt": [
                                { "$slice": [ "$messages", -1 ] },
                                0
                            ]
                        }
                    },
                    "in": "$$message.created"
                }
            }
        }}
    ]