簡體   English   中英

如何在MongoDB中獲取最近n個月的記錄(只考慮每月的最后一個條目)

[英]How to fetch the last n months record(consider only the last entry per month) in MongoDB

我是 MongoDb 的新手。 我需要幫助來獲取最后 n 個月的記錄,每個月可能有多個條目,但查詢只需要返回每個月的最后一個條目。

對於如讓說,如果n是3和用戶id userId1 (這意味着返回過去的3月歷史的userId1 )。

集合中的示例輸入:

[
 {
   "_id": objectId("aaaaaa"),
   "userId": "userId1",
   "processedAt": "2021-06-01T12:16:49.349Z"
 },
 {
   "_id": objectId("bbbbb"),
   "userId": "userId1",
   "processedAt": "2021-10-11T12:16:49.349Z"
 },
 {
   "_id": objectId("ccccc"),
   "userId": "userId1",
   "processedAt": "2021-10-25T12:16:49.349Z"
 },
 {
   "_id": objectId("eeeee"),
   "userId": "userId1",
   "processedAt": "2021-09-12T12:16:49.349Z"
 },
 {
   "_id": objectId("fffff"),
   "userId": "userId1",
   "processedAt": "2021-09-28T12:16:49.349Z"
 },
 {
   "_id": objectId("ggggg"),
   "userId": "userId1",
   "processedAt": "2021-09-23T12:16:49.349Z"
 },
 {
   "_id": objectId("hhhhh"),
   "userId": "userId1",
   "processedAt": "2021-07-23T12:16:49.349Z"
 },
 {
   "_id": objectId("iiiii"),
   "userId": "userId2",
   "processedAt": "2021-09-29T12:16:49.349Z"
 },
 {
   "_id": objectId("jjjjj"),
   "userId": "userId1",
   "processedAt": "2022-01-29T12:16:49.349Z"
 },
 {
   "_id": objectId("kkkkk"),
   "userId": "userId1",
   "processedAt": "2022-02-29T12:16:49.349Z"
 }, 
]

預期結果:應按userId返回,限制n個月(只獲取當月最后保存的條目)和processedAt月份的升序:

[{
    "_id": objectId("ccccc"),
    "userId": "userId1",
    "processedAt": "2021-10-25T12:16:49.349Z"
},
{
    "_id": objectId("jjjjj"),
    "userId": "userId1",
    "processedAt": "2022-01-29T12:16:49.349Z"
  },
  {
    "_id": objectId("kkkkk"),
    "userId": "userId1",
    "processedAt": "2022-02-29T12:16:49.349Z"
  }
]

我嘗試過下面的查詢,但是它返回了所有記錄。 我希望查詢只需要考慮每月的最后一個條目。 我一直在用mongojs驅動v4.1.2

db.collection(collection_name)
                .find({ userId: userId }, { projection: { _id: 0 } })
                .sort({ processedAt: -1 })
                .limit(n)
                .toArray()

從 MongoDB 5.0 開始

您可以使用$setWindowFields為“分區”/“組”(即您示例中的月份)聚合“排名”,並僅選擇排名最高的文檔。

排名可以定義為processedAt: -1因為您只想保留最高排名月份的最新記錄。

{
    "$setWindowFields": {
      "partitionBy": {
        "$dateToString": {
          "date": "$processedAt",
          "format": "%Y-%m"
        }
      },
      "sortBy": {
        "processedAt": -1
      },
      "output": {
        "rank": {
          $rank: {}
        }
      }
    }
  }

這是Mongo 游樂場供您參考。

對於 MongoDB 3.6+,

由於樣本數據集使用 ISODate 格式,因此可以按最左邊的 7 個字符(即 yyyy-MM)對字段進行排序和分組。 只保留月組中的第一個文檔應該可以解決問題。

{
    $sort: {
      processedAt: -1
    }
  },
  {
    "$addFields": {
      "month": {
        "$substrCP": [
          "$processedAt",
          0,
          7
        ]
      }
    }
  },
  {
    $group: {
      _id: "$month",
      last: {
        $first: "$$ROOT"
      }
    }
  }

這里是Mongo 游樂場

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM