【问题标题】:mongodb aggregation $group and then $push a objectmongodb 聚合 $group 然后 $push 一个对象
【发布时间】:2016-02-15 20:09:43
【问题描述】:

这是我的数据:

> db.bookmarks.find({"userId" : "56b9b74bf976ab70ff6b9999"}).pretty()
{
    "_id" : ObjectId("56c2210fee4a33579f4202dd"),
    "userId" : "56b9b74bf976ab70ff6b9999",
    "items" : [
        {
            "itemId" : "28",
            "timestamp" : "2016-02-12T18:07:28Z"
        },
        {
            "itemId" : "29",
            "timestamp" : "2016-02-12T18:07:29Z"
        },
        {
            "itemId" : "30",
            "timestamp" : "2016-02-12T18:07:30Z"
        },
        {
            "itemId" : "31",
            "timestamp" : "2016-02-12T18:07:31Z"
        },
        {
            "itemId" : "32",
            "timestamp" : "2016-02-12T18:07:32Z"
        },
        {
            "itemId" : "33",
            "timestamp" : "2016-02-12T18:07:33Z"
        },
        {
            "itemId" : "34",
            "timestamp" : "2016-02-12T18:07:34Z"
        }
    ]
}

我想要类似的东西(其实我希望 _id 也可以变成 userId):

{ 
    "_id" : "56b9b74bf976ab70ff6b9999", 
    "items" : [ 
        { "itemId": "32", "timestamp": "2016-02-12T18:07:32Z" },
        { "itemId": "31", "timestamp": "2016-02-12T18:07:31Z" },
        { "itemId": "30", "timestamp": "2016-02-12T18:07:30Z" }
    ] 
}

我现在拥有的:

> db.bookmarks.aggregate(
...     { $match: { "userId" : "56b9b74bf976ab70ff6b9999" } },
...     { $unwind: '$items' },
...     { $sort: { 'items.timestamp': -1} },
...     { $skip: 2 },
...     { $limit: 3},
...     { $group: { '_id': '$userId' , items: { $push: '$items.itemId' } } }
... ).pretty()
{ "_id" : "56b9b74bf976ab70ff6b9999", "items" : [ "32", "31", "30" ] }

我尝试在 mongo 中阅读文档并发现我可以 $push,但不知何故我找不到推送此类对象的方法,该对象未在整个对象的任何地方定义。我也想有时间戳..但我不知道我应该如何修改 $group (或其他人??)这样做。感谢您的帮助!

【问题讨论】:

    标签: mongodb aggregation-framework


    【解决方案1】:

    我在 MongoDB 3.2.1 shell 中测试过的这段代码应该会为您提供所需的输出格式:

    > db.bookmarks.aggregate( 
    { "$match" : { "userId" : "Ursula" } }, 
    { "$unwind" : "$items" }, 
    { "$sort" : { "items.timestamp" : -1 } }, 
    { "$skip" : 2 }, 
    { "$limit" : 3 }, 
    { "$group" : { "_id" : "$userId", items: { "$push" :  { "myPlace" : "$items.itemId", "myStamp" : "$items.timestamp" } } } }  ).pretty()
    

    运行上面会产生这个输出:

    {
        "_id" : "Ursula",
        "items" : [
            {
                "myPlace" : "52",
                "myStamp" : ISODate("2016-02-13T18:07:32Z")
            },
            {
                "myPlace" : "51",
                "myStamp" : ISODate("2016-02-13T18:07:31Z")
            },
            {
                "myPlace" : "50",
                "myStamp" : ISODate("2016-02-13T18:07:30Z")
            }
        ]
    }
    

    在 MongoDB 版本 3.2.x 中,您还可以在聚合管道的最后阶段使用 $out 运算符,并将聚合查询的输出写入集合。这是我使用的代码:

    > db.bookmarks.aggregate( 
    { "$match" : { "userId" : "Ursula" } }, 
    { "$unwind" : "$items" }, 
    { "$sort" : { "items.timestamp" : -1 } }, 
    { "$skip" : 2 }, 
    { "$limit" : 3 }, 
    { "$group" : { "_id" : "$userId", items: { "$push" :  { "myPlace" : "$items.itemId", "myStamp" : "$items.timestamp" } } } }, 
    { "$out" : "ursula" } ) 
    

    这给了我一个名为“ursula”的集合:

    > show collections
    ursula
    

    我可以查询该集合:

    > db.ursula.find().pretty()
    {
        "_id" : "Ursula",
        "items" : [
            {
                "myPlace" : "52",
                "myStamp" : ISODate("2016-02-13T18:07:32Z")
            },
            {
                "myPlace" : "51",
                "myStamp" : ISODate("2016-02-13T18:07:31Z")
            },
            {
                "myPlace" : "50",
                "myStamp" : ISODate("2016-02-13T18:07:30Z")
            }
        ]
    }
    > 
    

    最后,这是我在聚合查询中使用的输入文档。您可以将此文档与我编写聚合查询的方式进行比较,以了解我是如何构建新项目数组的。

    > db.bookmarks.find( { "userId" : "Ursula" } ).pretty()
    {
        "_id" : ObjectId("56c240ed55f2f6004dc3b25c"),
        "userId" : "Ursula",
        "items" : [
            {
                "itemId" : "48",
                "timestamp" : ISODate("2016-02-13T18:07:28Z")
            },
            {
                "itemId" : "49",
                "timestamp" : ISODate("2016-02-13T18:07:29Z")
            },
            {
                "itemId" : "50",
                "timestamp" : ISODate("2016-02-13T18:07:30Z")
            },
            {
                "itemId" : "51",
                "timestamp" : ISODate("2016-02-13T18:07:31Z")
            },
            {
                "itemId" : "52",
                "timestamp" : ISODate("2016-02-13T18:07:32Z")
            },
            {
                "itemId" : "53",
                "timestamp" : ISODate("2016-02-13T18:07:33Z")
            },
            {
                "itemId" : "54",
                "timestamp" : ISODate("2016-02-13T18:07:34Z")
            }
        ]
    }
    

    【讨论】:

    • 啊我也这么认为...但这只是我的疯狂猜测,我不确定在一次试验后我放弃了,也许我错过了一些括号或引用...无论如何,你帮我确认一下!非常感谢!!
    • 在这个阶段之后,我发现如何像重命名字段一样使用$project { $project: { userId: "$_id", items: 1, _id: 0 } }
    猜你喜欢
    • 2019-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-08
    • 2021-12-18
    • 1970-01-01
    • 2020-11-09
    • 2023-03-07
    相关资源
    最近更新 更多