Mongodb 获取每个子文档具有最大值的文档

问题描述 投票:0回答:2

我有一些数据如下:

    {'Type':'A',
     'Attributes':[
            {'Date':'2021-10-02', 'Value':5},
            {'Date':'2021-09-30', 'Value':1},
            {'Date':'2021-09-25', 'Value':13}
       ]
     },
    {'Type':'B',
     'Attributes':[
            {'Date':'2021-10-01', 'Value':36},
            {'Date':'2021-09-15', 'Value':14},
            {'Date':'2021-09-10', 'Value':18}
       ]
     }

我想查询每个文档的最新日期的文档。根据以上数据,期望的结果将是:

{'Type':'A', 'Date':'2021-10-02', 'Value':5}
{'Type':'B', 'Date':'2021-10-01', 'Value':36}

我设法找到一些查询来查找所有子文档中的全局最大值。但我没有找到每个文档的最大值。

非常感谢您的帮助

mongodb mongodb-query pymongo
2个回答
2
投票

从 MongoDB v5.0+ 开始,您可以使用

$setWindowFields
计算
$rank
文档的
$unwind
并选择
rank: 1
条目。

db.collection.aggregate([
  {
    "$unwind": "$Attributes"
  },
  {
    "$setWindowFields": {
      "partitionBy": "$_id",
      "sortBy": {
        "Attributes.Date": -1
      },
      "output": {
        "rank": {
          "$rank": {}
        }
      }
    }
  },
  {
    "$match": {
      "rank": 1
    }
  },
  {
    $project: {
      Type: 1,
      Date: "$Attributes.Date",
      Value: "$Attributes.Value"
    }
  }
])

蒙戈游乐场

将日期存储为字符串通常被认为是不好的做法。建议您将日期字段更改为日期类型。幸运的是,对于您的情况,您使用的是 ISO 日期格式,因此可以节省一些精力。

您可以在聚合管道中执行此操作:

  1. 使用
    $max
    找出最大日期
  2. 使用
    $filter
    过滤
    Attributes
    数组以仅包含最新元素
  3. $unwind
    数组
  4. $project
    达到您的预期输出
db.collection.aggregate([
  {
    "$addFields": {
      "maxDate": {
        $max: "$Attributes.Date"
      }
    }
  },
  {
    "$addFields": {
      "Attributes": {
        "$filter": {
          "input": "$Attributes",
          "as": "a",
          "cond": {
            $eq: [
              "$$a.Date",
              "$maxDate"
            ]
          }
        }
      }
    }
  },
  {
    $unwind: {
      path: "$Attributes",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    $project: {
      Type: 1,
      Date: "$Attributes.Date",
      Value: "$Attributes.Value"
    }
  }
])

这里是Mongo游乐场供您参考。


0
投票

这仅保留属性中的 1 名成员,即具有最大日期的成员。 如果您想保留多个成员,请使用 @ray 解决方案,该解决方案保留具有最大日期的所有成员。

*mongoplayground 可能会丢失文档中字段的顺序, 如果你看到错误的结果,请在你的驱动程序上测试它,这是 mongoplayground 工具的错误

查询1(本地方式)

在这里测试代码

aggregate([
  {
    "$project": {
      "maxDateValue": {
        "$max": {
          "$map": {
            "input": "$Attributes",
            "in": { "Date": "$$this.Date", "Value": "$$this.Value" },
           }
         }
       },
      "Type": 1
     }
   },
  {
    "$project": {
      "Date": "$maxDateValue.Date", 
      "Value": "$maxDateValue.Value"
    }
  }
])

查询2(展开方式)

在这里测试代码

aggregate([
  {
    "$unwind": { "path": "$Attributes" }
  },
  {
    "$group": {
      "_id": "$Type",
      "maxDate": {
        "$max": {
          "Date": "$Attributes.Date", 
          "Value": "$Attributes.Value"
        }
      }
    }
  },
  {
    "$project": {
      "_id": 0,
      "Type": "$_id",
      "Date": "$maxDate.Date",
      "Value": "$maxDate.Value"
    }
  }
])
© www.soinside.com 2019 - 2024. All rights reserved.