英文:
MongoDB Aggregation - How to get upper boundary in $bucket stage?
问题
以下是翻译的内容:
"Lower boundary" 是 "1860",它在 _id 字段中表示,但如何获取 "upper boundary",也就是 "1870" 呢?
谢谢!
英文:
Let's say one has data below:
[
  { "_id" : 1, "last_name" : "Bernard", "first_name" : "Emil", "year_born" : 1868, "year_died" : 1941, "nationality" : "France" },
  { "_id" : 2, "last_name" : "Rippl-Ronai", "first_name" : "Joszef", "year_born" : 1861, "year_died" : 1927, "nationality" : "Hungary" }
]
Then runs $bucket stage :
db.artists.aggregate( [
  {
    $bucket: {
      groupBy: "$year_born",                        // Field to group by
      boundaries: [ 1840, 1850, 1860, 1870, 1880 ], // Boundaries for the buckets
      default: "Other",                             // Bucket ID for documents which do not fall into a bucket
      output: {                                     // Output for each bucket
        "count": { $sum: 1 },
        "artists" :
          {
            $push: {
              "name": { $concat: [ "$first_name", " ", "$last_name"] },
              "year_born": "$year_born"
            }
          }
      }
    }
  }
] );
The output is like this:
{ 
  "_id" : 1860, 
  "count" : 2, 
  "artists" : [ 
    { "name" : "Emil Bernard", "year_born" : 1868 },
    { "name" : "Joszef Rippl-Ronai", "year_born" : 1861 } 
  ] 
}
Example reference: MongoDB $bucket aggregation
-- Question --
Lower boundary is 1860 which is represented in the _id field, but how to get the upper boundary which is 1870?
Thank you!
答案1
得分: 3
没有 Mongo 的方式来做这个。
如果年份是硬编码的,你可以使用 $addFields 添加自定义逻辑,如下所示:
{
  "$addFields": {
    "upperBound": {
      "$sum": [
        "$_id",
        10
      ]
    }
  }
}
如果它们是动态传递的,你可以使用类似的方法,只需提取数组中的下一个元素:
const boundaries: [ 1840, 1850, 1860, 1870, 1880 ]
db.collection.aggregate([
  {
    "$bucket": {
      "groupBy": "$year_born",
      "boundaries": boundaries,
      "default": "Other",
      "output": {
        "count": {
          "$sum": 1
        },
        "artists": {
          "$push": {
            "name": {
              "$concat": [
                "$first_name",
                " ",
                "$last_name"
              ]
            },
            "year_born": "$year_born"
          }
        }
      }
    }
  },
  {
    "$addFields": {
      "upperBound": {
        "$arrayElemAt": [
          boundaries,
          {
            "$sum": [
              {
                "$indexOfArray": [
                  boundaries,
                  "$_id"
                ]
              },
              1
            ]
          }
        ]
      }
    }
  }
])
英文:
There's no Mongo-y way to do this.
If the years are hard coded you can just add this custom logic with an $addFields, like so:
  {
    $addFields: {
      upperBound: {
        $sum: [
          "$_id",
          10
        ]
      }
    }
  }
If they are passed dynamically you can use a similar approach and just extract the next element in the array:
const boundaries: [ 1840, 1850, 1860, 1870, 1880 ]
db.collection.aggregate([
  {
    $bucket: {
      groupBy: "$year_born",
      // Field to group by
      boundaries: boundaries,
      // Boundaries for the buckets
      default: "Other",
      // Bucket ID for documents which do not fall into a bucket
      output: {
        // Output for each bucket
        "count": {
          $sum: 1
        },
        "artists": {
          $push: {
            "name": {
              $concat: [
                "$first_name",
                " ",
                "$last_name"
              ]
            },
            "year_born": "$year_born"
          }
        }
      }
    }
  },
  {
    $addFields: {
      upperBound: {
        "$arrayElemAt": [
          boundaries,
          {
            $sum: [
              {
                "$indexOfArray": [
                  boundaries,
                  "$_id"
                ]
              },
              1
            ]
          }
        ]
      }
    }
  }
])
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论