【问题标题】:How to return whole document from aggregation如何从聚合中返回整个文档
【发布时间】:2023-03-26 17:10:01
【问题描述】:

我目前正在使用 MonGODB v2.6.4,除了 Robomongo 还不支持 MongoDB v3.0 之外没有其他原因。

使用以下示例文档,如果它不是我想要做的事情的简化示例,我将不会采用这种方式来构建它们。

db.visitors.insert({
    "visits" : [{"building" : "building01", "lastVisit" : new ISODate("2015-02-01 17:05:00")},
                {"building" : "building02", "lastVisit" : new ISODate("2015-02-04 04:25:00")},
                {"building" : "building03", "lastVisit" : new ISODate("2015-02-07 15:45:00")},
                {"building" : "building04", "lastVisit" : new ISODate("2015-02-10 15:45:00")}
               ],

 "firstName" : "John",
 "lastName" : "Smith",
 "gender" : "male",
 "accountNumber" : "123456789",
 });

db.visitors.insert({
    "visits" : [{"building" : "building01", "lastVisit" : new ISODate("2015-02-02 17:05:00")},
                {"building" : "building02", "lastVisit" : new ISODate("2015-02-05 04:25:00")},
                {"building" : "building03", "lastVisit" : new ISODate("2015-02-08 15:45:00")},
                {"building" : "building04", "lastVisit" : new ISODate("2015-02-11 15:45:00")}
               ],

 "firstName" : "Jane",
 "lastName" : "Smith",
 "gender" : "female",
 "accountNumber" : "987654321",
 });

db.visitors.insert({
    "visits" : [{"building" : "building01", "lastVisit" : new ISODate("2015-02-03 17:05:00")},
                {"building" : "building02", "lastVisit" : new ISODate("2015-02-06 04:25:00")},
                {"building" : "building03", "lastVisit" : new ISODate("2015-02-09 15:45:00")},
                {"building" : "building04", "lastVisit" : new ISODate("2015-02-12 15:45:00")}
               ],

 "firstName" : "James",
 "lastName" : "Smith",
 "gender" : "male",
 "accountNumber" : "123056780",
 });

我想找到特定建筑物的最后一位访客,并且需要该访客返回的整个文档。

我已经完成了这个聚合查询,几乎可以满足我的需求:

db.visitors.aggregate([
  {$match: {"visits.building": "building02"}},
  {$unwind: "$visits"},
  {$project: {"visitorId": "$_id", "building": "$visits.building", "lastVisit": "$visits.lastVisit"}},
  {$sort: {"lastVisit": 1}},
  {$group: {"_id": "$building", "visitorId": {$last: "$visitorId"}, "lastVisit": {$last: "$lastVisit"}}},
  {$match: {"_id": "building02"}},
  {$limit: 1}
])

并返回这个结构:

{
    "result" : [ 
        {
            "_id" : "building02",
            "visitorId" : ObjectId("55098990ca5b44f2858f4cb5"),
            "lastVisit" : ISODate("2015-02-12T15:45:00.000000:00")
        }
    ],
    "ok" : 1.0000000000000000
}

如何修改聚合查询以返回整个访问者文档而不仅仅是访问者 ID?我已经尝试过(使用$$ROOT$$CURRENT 失败了)。

如果返回整个文档是不可能的,那么我该如何对返回的结果结构进行查找,以便我可以通过 id 检索它?我一直在尝试这个主题的变化:

var result = db.visitors.aggregate([
  {$match: {"visits.building": "building02"}},
  {$unwind: "$visits"},
  {$project: {"visitorId": "$_id", "building": "$visits.building",  "lastVisit": "$visits.lastVisit"}},
  {$sort: {"lastVisit": 1}},
  {$group: {"_id": "$building", "visitorId": {$last: "$visitorId"}, "lastVisit": {$last: "$lastVisit"}}},
  {$match: {"_id": "building02"}},
  {$limit: 1}
])

db.individuals.find({_id: {$eq: {result.visitorId: {$slice: [0, 1]}}}})

我更愿意在一个查询中完成所有事情,但如果我不能,那么我就不能。

【问题讨论】:

    标签: mongodb mongodb-query


    【解决方案1】:

    您不需要 $group,因此无需担心$$ROOT 或努力找回所有字段。您将获得原始文档的(副本),其中仅在 visits 数组中留下了最近一次访问。

    > db.visitors.aggregate([ 
        { "$match" : { "visits.building" : "building02" } },
        { "$unwind" : "$visits" }, 
        { "$match" : { "visits.building" : "building02" } },
        { "$sort" : { "visits.lastVisit" : -1 } }, { "$limit" : 1 }
    ])
    {
        "_id" : ObjectId("5509e963b8b4702f49ffcee6"),
        "visits" : {
            "building" : "building02",
            "lastVisit" : ISODate("2015-02-06T04:25:00Z")
        },
        "firstName" : "James",
        "lastName" : "Smith",
        "gender" : "male",
        "accountNumber" : "123056780"
    }
    

    如果您想要整个visits 数组,那么我只需将_id 通过管道投影并在管道返回后对其进行查找,以获取整个文档。

    【讨论】:

    • 所以我的查询中的 $group 是不必要的,$project 实际上隐藏了我想要的结果。哦!您的更改正是我想要的,谢谢。
    猜你喜欢
    • 2014-01-29
    • 2021-11-16
    • 2021-06-01
    • 2020-08-26
    • 2015-08-26
    • 2019-06-26
    • 1970-01-01
    • 2020-04-26
    • 2015-06-24
    相关资源
    最近更新 更多