【问题标题】:MongoDB: group, and then counting different valuesMongoDB:分组,然后计算不同的值
【发布时间】:2020-11-13 05:07:30
【问题描述】:

我有一个书单。我想得到作者写的类型的数量,我也想添加这些类型的结果。我的数据库如下所示:

{"_id": ObjectID("1), "title": "Harry Potter", "year": NumberInt(2000), "author": "JK. Rowling", 
"genres": "Fantasy"}, 
"_id": ObjectID("2"), "title": "Harry Potter 99", "year": NumberInt(2020), "author": "JK. Rowling", 
"genres": "Drama"}, "_id": ObjectID("2"), "title": "Harry Potter", "year": NumberInt(2000), "author": "JK. Rowling", 
"genres": "Drama"}, {...}

所以,到目前为止,我的代码如下所示:

phase1 = {$group : {"_id" : "$author"}, "countgenres" : {$sum : 1}}
phase2 = {$addFields : "genres"}}
phase3 = {$sort : {"numgenres" : -1}}

steps = [phase1, phase2, phase3]
db.database.aggregate(steps)

这对我不起作用,所以我希望有人可以帮助我编写正确的代码来执行此操作。结果应如下所示:

{

"_id" : "JK. Rowling",

"countgenres" : 4,

"genres" : [

"War",
"Fantasy",
"Drama",
"Crime"

]
}

谢谢。

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    你不能直接在 $group 阶段这样做。取而代之的是,您必须使用 $addFields 阶段并使用 $reduce$setUnion 来连接没有双精度的数组。 然后,您可以添加一个具有新数组大小的字段,然后执行 $sort。

    db.collection.aggregate([
      {
        $group: {
          _id: "$author",
          genres: {
            $push: "$genres"
          }
        }
      },
      {
        $addFields: {
          genres: {
            "$reduce": {
              "input": "$genres",
              "initialValue": [],
              "in": {
                $setUnion: [
                  "$$value",
                  "$$this"
                ]
              }
            }
          }
        }
      },
      {
        $addFields: {
          countGenres: {
            $size: "$genres"
          }
        }
      }
    ])
    

    You can test here

    【讨论】:

    • 您好,谢谢!我刚刚意识到我发布了一个错误的数据库示例,在我的数据库中,每个文档只有一个流派(我之前已经对流派进行了展开)。因此,同一本书可以以不同的体裁出现两次。我不知道这是否会改变什么,或者我是否应该打开一个新的威胁。
    • 最好开个新的
    【解决方案2】:

    试试这个查询:

    db.collection.aggregate([
      {
        "$match": {
          "author": "JK. Rowling"
        }
      },
      {
        "$group": {
          "_id": "$author",
          "genres": {
            "$addToSet": "$genres"
          }
        }
      },
      {
        $addFields: {
          genres: {
            "$reduce": {
              "input": "$genres",
              "initialValue": [],
              "in": {
                $setUnion: [
                  "$$value",
                  "$$this"
                ]
              }
            }
          }
        }
      },
      {
        "$project": {
          "countgenres": {
            "$size": "$genres"
          },
          "genres": 1
        }
      }
    ])
    

    第一阶段是作者$match

    然后分组,我使用$addToSet 来避免重复值。
    之后,与$addFields 值合并。

    分组后,字段genres输出如下:

    "genres": [
          [
            "War",
            "Fantasy",
            "Drama",
            "Crime"
          ],
          [
            "War",
            "Fantasy",
            "Drama"
          ]
        ]
    

    合并是必要的$setUnion

    最后一步是计算数组大小并输出你想要的值。

    例如here

    【讨论】:

    • 您好,谢谢!我刚刚意识到我发布了一个错误的数据库示例,在我的数据库中,每个文档只有一个流派(我之前已经对流派进行了展开)。因此,同一本书可以以不同的体裁出现两次。我不知道这是否会改变什么,或者我是否应该打开一个新的威胁。
    • 尝试像这样输入$setUnion$setUnion: [ "$$value", [ "$$this" ] ],也许它会起作用。
    猜你喜欢
    • 2019-06-09
    • 1970-01-01
    • 2018-08-17
    • 1970-01-01
    • 2018-07-03
    • 1970-01-01
    • 2015-04-22
    • 2022-11-22
    • 1970-01-01
    相关资源
    最近更新 更多