【问题标题】:Is there a way to set my field values in MongoDB query dynamic?有没有办法在 MongoDB 查询中动态设置我的字段值?
【发布时间】:2020-08-04 07:52:39
【问题描述】:

我正在运行 MongoDB 查询并尝试更改输出的结构方式。目前看起来如下:

[
  {
    qClass: [
      {
        cat: 'Servers',
        class: 'High Impact Maintenance',
        total: 1
      },
      {
        cat: 'Network.TrafficShapers',
        class: 'Maintenance',
        total: 16
      },
      {
        cat: 'Network.Hop',
        class: 'Core Failure',
        total: 2
      },
      {
        cat: 'Office.MFD',
        class: 'Failure',
        total: 4
      },
      {
        cat: 'Office.Printers',
        class: 'Maintenance',
        total: 36
      },
      {
        cat: 'Office.MFD',
        class: 'Maintenance',
        total: 880
      },
      {
        cat: 'Network.TrafficShapers',
        class: 'Failure',
        total: 47
      },
      {
        cat: 'Servers',
        class: 'Core Maintenance',
        total: 1
      },
      {
        cat: 'Network.Switches',
        class: 'Failure',
        total: 5
      },
      {
        cat: 'Servers',
        class: 'Performance',
        total: 21
      },
      {
        cat: 'Network.Switches',
        class: 'High Impact Failure',
        total: 4
      },
      {
        cat: 'Network.Firewall',
        class: 'Core Failure',
        total: 2
      },
      {
        cat: 'Network.Router',
        class: 'Failure',
        total: 53
      },
      {
        cat: 'Servers',
        class: 'High Impact Failure',
        total: 3
      },
      {
        cat: 'Office.Printers',
        class: 'Performance',
        total: 1
      },
      {
        cat: 'Network.TrafficShapers',
        class: 'Performance',
        total: 3
      },
      {
        cat: 'Network.Switches',
        class: 'Maintenance',
        total: 1
      },
      {
        cat: 'Servers',
        class: 'Failure',
        total: 60
      },
      {
        cat: 'Network.Router',
        class: 'Performance',
        total: 67
      },
      {
        cat: 'Network.Router',
        class: 'High Impact Failure',
        total: 39
      },
      {
        cat: 'Office.MFD',
        class: 'Performance',
        total: 5
      },
      {
        cat: 'Network.TrafficShapers',
        class: 'High Impact Failure',
        total: 593
      },
      {
        cat: 'Network.Router',
        class: 'Maintenance',
        total: 78
      },
      {
        cat: 'Office.Printers',
        class: 'High Impact Failure',
        total: 2
      },
      {
        cat: 'Office.Printers',
        class: 'Failure',
        total: 1
      },
      {
        cat: 'Office.MFD',
        class: 'Critical Failure',
        total: 48
      }
    ]
  }
] 

我希望它的结构如下:

{
    cat: 'Servers',
    High Impact Maintenance: 1,
    Performance: 24,
   Total: 25
} 

所以基本上,所有关于 cat (category) 的信息都在同一个数组中,并且字段名称对于类是动态的。以下是我为此使用的查询:

db.full_ticket_lists.aggregate(
  {
    
    $facet: {
            qClass: [
          {$match : {"device":{$ne:null},"status":"Open","ticket_class":{$ne:''}}},
          {$lookup: { from: "devices", localField: "device",  foreignField: "_id", as: "device_link"},},
          {$lookup: { from: "device_categories", localField: "device_link.device_category",  foreignField: "_id", as: "category_link"},},
          {$unwind: "$category_link"},
          {$group : {
                      _id:{"class_name":"$ticket_class", "cat_name":"$category_link.name"}, 
                      count: {$sum:1}
          },},
          {$project:{_id:0,cat:"$_id.cat_name", class:"$_id.class_name",total:"$count"}}
      ],
    }
  }
) 

【问题讨论】:

  • 其他收藏在哪里?或者你只是想做你提供的第一个json?所以我准备了这样mongoplayground.net/p/vyGaHfXWJ0z这有用吗?
  • @turivishal 非常有帮助,非常感谢,它解决了我的问题!我在下面的部分中有点迷失了,介意向我解释它的作用吗? { $replaceRoot: { newRoot: { $mergeObjects: [ "$$ROOT", { $arrayToObject: "$classes" } ] } } },

标签: node.js mongodb mongodb-query


【解决方案1】:

一步一步看,专注于你预期的结果,

{
  "cat": 'Servers',
  "High Impact Maintenance": 1,
  "Performance": 24,
  "Total": 25
} 
  • $unwind qClass 因为它是一个数组,我们需要 $group 部分下面的每个对象
  • $groupcat
  • 创建classesclass 作为k(key) 和total 作为v(value)
  • 创建total 以推送所有total 的总和
db.collection.aggregate([
  {
    $unwind: "$qClass"
  },
  {
    $group: {
      _id: "$qClass.cat",
      cat: {
        $first: "$qClass.cat"
      },
      classes: {
        $push: {
          k: "$qClass.class",
          v: "$qClass.total"
        }
      },
      total: {
        $sum: "$qClass.total"
      }
    }
  },
  • $replaceRoot 将用新数组替换根目录
  • $mergeObjects 将首先合并两个对象 $$ROOT 和第二个 $classes ,后者从数组转换为对象
  • $arrayToObjectclasses 数组转换为对象,它将 k(key) 和 v(value) 转换为对象
  {
    $replaceRoot: {
      newRoot: {
        $mergeObjects: [
          "$$ROOT",
          {
            $arrayToObject: "$classes"
          }
        ]
      }
    }
  },
  • $project 将隐藏不需要的字段(0 = 隐藏,1 = 显示) 所以这里 _idclasses 都被隐藏了,不再需要了
  {
    $project: {
      _id: 0,
      classes: 0
    }
  }
])

游乐场:https://mongoplayground.net/p/vyGaHfXWJ0z

【讨论】:

    猜你喜欢
    • 2021-11-13
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-24
    • 2015-11-19
    相关资源
    最近更新 更多