MongoDB:如何按一个字段分组,在组中找到最大字段并输出整个记录

时间:2019-06-13 03:59:37

标签: mongodb aggregate

我每隔几秒钟就会将用户的位置添加到文档中,我需要查询并返回用户的最新位置和时间列表。

文档样本记录如下。 (当然,有很多这样的记录。)

{ 
    "_id" : ObjectId("5c99185292e2243299768611"), 
    "user_id" : ObjectId("5c898f5f92e224329827027f"), 
    "time" : ISODate("2019-03-25T18:05:06.000+0000"), 
    "location" : {
        "type" : "Point", 
        "coordinates" : [
            -122.98866207168987, 
            49.213194044878996
        ]
    }
}

以下代码始终返回“ TypeError:db.getCollection(...)。aggregate(...)。result未定义”:

db.getCollection("user_location").aggregate(
    [
        { 
            "$group" : {
                "_id" : {
                    "user_id" : "$user_id"
                }, 
                "time" : {
                    "$max" : "$time"
                }
            }
        }, 
        { 
            "$project" : {
                "user_id" : "$_id.user_id", 
                "time" : "$MAX(time)", 
                "_id" : NumberInt(0)
            }
        }
    ], 
    { 
        "allowDiskUse" : true
    }
).result.forEach(function(match) {
    // Find matching documents per group and push onto results array
    results.push(db.user_location.findOne(match));
});

预期的行为是输出文档中的所有字段。

1 个答案:

答案 0 :(得分:0)

我首先对整个集合进行排序,然后按用户ID进行分组,然后将每个文档推送到“ docs”中,因为对集合进行了排序,这些仍然是按顺序排列的。然后,我将每个玩家的文档替换为“文档”字段中的第一个文档。

db.collection.aggregate([
  {
    "$sort": { "time": -1 }
  },
  { 
    "$group" : {
      "_id" :"$user_id",
      "docs" : {
        "$push": "$$ROOT"
      }
    }
  },
  {
    "$replaceRoot": {
       "newRoot": {
         "$arrayElemAt": ["$docs",0]
       } 
    }
  }
], 
{ 
    "allowDiskUse" : true
})