【问题标题】:Need help on Mongo Db Query to fetch data需要有关 Mongo Db Query 的帮助以获取数据
【发布时间】:2021-08-17 10:47:23
【问题描述】:

给定一个名为 users 的现有 mongo db 集合,其中包含一些文档,如下所示:

{
    "_id" : ObjectId("611a11a09500700009d09a12"),
    "userId" : "abc",
    "createdAt" : ISODate("2021-08-14T07:22:00.535Z"),
    "isActive" : true,
    "isEligible" : true
},
{
    "_id" : ObjectId("611a11a09500700009d09a13"),
    "userId" : "abc",
    "createdAt" : ISODate("2021-08-15T07:20:00.535Z"),
    "isActive" : true,
    "isEligible" : true
},
{
    "_id" : ObjectId("611a11a09500700009d09a14"),
    "userId" : "def",
    "createdAt" : ISODate("2021-08-15T07:22:00.535Z"),
    "isActive" : true,
    "isEligible" : true
},
{
    "_id" : ObjectId("611a11a09500700009d09a15"),
    "userId" : "abc",
    "createdAt" : ISODate("2021-08-16T07:18:00.535Z"),
    "isActive" : true,
    "isEligible" : true
},
{
    "_id" : ObjectId("611a11a09500700009d09a16"),
    "userId" : "abc",
    "createdAt" : ISODate("2021-08-16T07:20:00.535Z"),
    "isActive" : true,
    "isEligible" : true
}
{
    "_id" : ObjectId("611a11a09500700009d09a17"),
    "userId" : "def",
    "createdAt" : ISODate("2021-08-16T07:22:00.535Z"),
    "isActive" : true,
    "isEligible" : true
}

除了上面每个文档中提到的键之外,还可以有多个其他键。

在这里,我想编写一个执行以下操作并返回数据的查询:

  1. 选择 createdAt 大于或等于“2021-08-15T00:00:00.000Z”的记录
  2. 对于每个 userId,仅返回最新记录,即按 createdAt 降序排序的记录。
  3. 返回的文档应该包含原始文档中存在的所有键。键的数量可能比文档中显示的要多得多。因此,查询应该自动返回所有键。

以下是所需的示例输出:

{
    "_id" : ObjectId("611a11a09500700009d09a16"),
    "userId" : "abc",
    "createdAt" : ISODate("2021-08-16T07:20:00.535Z"),
    "isActive" : true,
    "isEligible" : true
}
{
    "_id" : ObjectId("611a11a09500700009d09a17"),
    "userId" : "def",
    "createdAt" : ISODate("2021-08-16T07:22:00.535Z"),
    "isActive" : true,
    "isEligible" : true
}

【问题讨论】:

    标签: mongodb mongodb-query


    【解决方案1】:

    你可以使用这个聚合阶段:

    • 首先$match 仅获取日期大于或等于所需日期的文档。
    • 然后$sort 设置按降序排列的第一个位置值。
    • 最后$group by userId 只获得第一个值(按-1 排序,第一个值将根据desc 排序)
    db.collection.aggregate([
      {
        "$match": {
          "createdAt": {
            "$gte": ISODate("2021-08-15T00:00:00.000Z")
          }
        }
      },
      {
        "$sort": {
          "createdAt": -1
        }
      },
      {
        "$group": {
          "_id": "$userId",
          "createdAt": {
            "$first": "$createdAt"
          }
        }
      }
    ])
    

    例如here

    另外,如果在最终结果中获得ObjectId 对您很重要,您还可以添加一个阶段,例如this

    【讨论】:

    • 感谢您的回答。只是一个更新,在您的回答中,我们需要提及我们需要在“$project”运算符中手动返回的所有键。但是,我希望查询自动返回所有键,因为键的数量可能很大。我还用更清晰的说明更新了问题,如果您能提供解决方案的更新,我将不胜感激。
    • 你的意思是像this。请注意,我添加了一个新值newValue,如果存在则显示,否则将为空。但是您必须手动将所有选项添加到 $project 中,或者将值设置到 data 字段中,例如 this
    • 自从没有。键可能很大,很难手动将所有选项添加到 $project 中,我希望查询按 userId 对数据进行分组并为每个 userId 选择最新条目并返回最新记录的所有键显示在示例响应中。
    • 然后你可以使用this query 使用$replaceRoot。如果它适合你,我可以编辑我的答案。
    • 您提到的使用 $replaceRoot 的查询以所需的相同格式返回结果。但是,它不维护 createdAt 上的排序顺序。当我多次运行查询时,记录没有按 createdAt 的降序排序。您可以在mongoplayground.net/p/Q4A0UJ_E4u2 上看到相同的内容
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多