【问题标题】:MongoDB compass - Get the field name (key) with the max value, from 3 fields and their values in a documentMongoDB compass - 从文档中的 3 个字段及其值中获取具有最大值的字段名称(键)
【发布时间】:2020-02-25 03:13:13
【问题描述】:

我有这个示例 mongodb 文档 -

{
    _id: 5db85ee97d9fb13ead4fc54c
    applId: 5d48f34f7d9fb10ce171f905
    fileId: "dd386cf7-4139-45c2-9853-cbb126621b51"
    job: Object
    country: "US"
    fullName: "abcd xyz"
    htmlWordCount: 2766
    textWordCount: 1867
    rchilliTextWordCount: 2840
    deleted: 0
    dateEntered: 2019-10-29 15:46:49.237
    dateModified: 2019-10-29 15:46:49.237
}

我想在 compass 中构建一个查询,以便在输出中有以下字段 -

{
    _id: 5db85ee97d9fb13ead4fc54c
    country: "US"
    fullName: "abcd xyz"
    htmlWordCount: 2766
    textWordCount: 1867
    rchilliTextWordCount: 2840
    winner: "rchilliTextWordCount"
}

请注意,它有一个名为“winner”的新字段,它始终返回字数最多的列(在 3 个"htmlWordCount", "textWordCount", "rchilliTextWordCount" 列中)。这个新列"winner" 将在运行时查询时生成。此查询也在country = "US" 上过滤。

如何在 MongoDB Compass 中执行此操作,或者聚合管道应该是什么样的?

【问题讨论】:

    标签: mongodb aggregation-framework mongodb-compass


    【解决方案1】:

    您可以使用$switch$cond

    db.collection.aggregate([
      {
        $match: {
          country: "US"
        }
      },
      {
        $project: {
          country: 1,
          fullName: 1,
          htmlWordCount: 1,
          textWordCount: 1,
          rchilliTextWordCount: 1,
          winner: {
            $switch: {
              branches: [
                {
                  case: {
                    $and: [
                      {
                        $gt: [
                          "$htmlWordCount",
                          "$textWordCount"
                        ]
                      },
                      {
                        $gt: [
                          "$htmlWordCount",
                          "$rchilliTextWordCount"
                        ]
                      }
                    ]
                  },
                  then: "htmlWordCount"
                },
                {
                  case: {
                    $and: [
                      {
                        $gt: [
                          "$textWordCount",
                          "$htmlWordCount"
                        ]
                      },
                      {
                        $gt: [
                          "$textWordCount",
                          "$rchilliTextWordCount"
                        ]
                      }
                    ]
                  },
                  then: "textWordCount"
                },
                {
                  case: {
                    $and: [
                      {
                        $gt: [
                          "$rchilliTextWordCount",
                          "$htmlWordCount"
                        ]
                      },
                      {
                        $gt: [
                          "$rchilliTextWordCount",
                          "$textWordCount"
                        ]
                      }
                    ]
                  },
                  then: "rchilliTextWordCount"
                }
              ],
              default: "No winners"
            }
          }
        }
      }
    ])
    

    MongoPlayground

    【讨论】:

      【解决方案2】:

      这是获取结果的另一种方法:

      1. 获取文档的字段名称及其值
      2. 查找名称在[ "htmlWordCount", "textWordCount", "rchilliTextWordCount" ] 中的字段的最大值。

      一般来说,从一个数组中求一个最大值是一种归约;所以我在这种情况下使用了$reduce。注意代码更简单。如果您想添加另一个字段来计算最大值,只需将其添加到数组中即可。

      db.winner.aggregate([
        { $match: { country: "US"} },
        { $addFields: { fieldNameValues: { "$objectToArray": "$$ROOT" } } },
        { $project: { _id: 1, country: 1, fullName: 1, htmlWordCount: 1, textWordCount: 1, rchilliTextWordCount: 1, 
                      winner: { 
                          $reduce: {
                              input: "$fieldNameValues",
                              initialValue: { },
                              in: {
                                  $cond: [
                                     { $and: [ 
                                         { $in: [ "$$this.k", [ "htmlWordCount", "textWordCount", "rchilliTextWordCount" ] ] }, 
                                         { $gt: [ "$$this.v", "$$value.v"] } ]
                                     },
                                     "$$this",
                                     "$$value"
                                  ]
                              }
                          } 
                     } 
        } },
        { $addFields: { winner: "$winner.k" } }
      ] )
      



      [编辑添加]

      样本数据和结果:

      {
              "_id" : 1,
              "fileId" : "dd386cf7-4139-45c2-9853-cbb126621b51",
              "job" : { },
              "country" : "US",
              "fullName" : "abcd xyz",
              "htmlWordCount" : 2766,
              "textWordCount" : 1867,
              "rchilliTextWordCount" : 2840
      }
      {
              "_id" : 2,
              "fileId" : "dd386cf7-4139-45c2-9853-cbb126621b51",
              "job" : { },
              "country" : "US",
              "fullName" : "lmn opqrs",
              "htmlWordCount" : 5,
              "textWordCount" : 9,
              "rchilliTextWordCount" : 2
      }
      

      输出:

      {
              "_id" : 1,
              "country" : "US",
              "fullName" : "abcd xyz",
              "htmlWordCount" : 2766,
              "textWordCount" : 1867,
              "rchilliTextWordCount" : 2840,
              "winner" : "rchilliTextWordCount"
      }
      {
              "_id" : 2,
              "country" : "US",
              "fullName" : "lmn opqrs",
              "htmlWordCount" : 5,
              "textWordCount" : 9,
              "rchilliTextWordCount" : 2,
              "winner" : "textWordCount"
      }
      

      【讨论】:

      • 是的,这也有效。我猜这个效率更高?
      • 我不能用可用的信息说哪个更好。只能从一些真实数据的尝试、使用场景以及维护和性能的角度来判断。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-19
      相关资源
      最近更新 更多