首页 > 解决方案 > 在 MongoDB 中形成具有聚合的数组

问题描述

我在 MongoDB 3.4 中有一个具有以下结构的文档:

{
    "_id" : ObjectId("5e3419e468d01013eadb83dc"),
    "id_station" : "62",
    "fiware_service" : null,
    "fiware_servicepath" : null,
    "id_fiware_name" : "CE_del_medio",
    "attrName" : "15",
    "attrType" : "float",
    "attrValue" : 0.33,
    "id_sensor_station_absolute" : "15_62",
    "recvTimeTs" : 1580387045,
    "recvTime" : "2020-01-30T12:24:05.00Z",
    "id_fiware" : "15",
    "sensor_type" : [ 
        {
            "name" : "id",
            "type" : "String",
            "value" : "15"
        }, 
        {
            "name" : "img",
            "type" : "String",
            "value" : "assets/img/contrast.png"
        }, 
        {
            "name" : "manufacturer",
            "type" : "String",
            "value" : "Hortisis"
        }, 
        {
            "name" : "medida",
            "type" : "String",
            "value" : "mS/cm"
        }, 
        {
            "name" : "name_comun",
            "type" : "String",
            "value" : "CE del medio"
        }, 
        {
            "name" : "place",
            "type" : "String",
            "value" : "interior"
        }, 
        {
            "name" : "timestamp",
            "type" : "DateTime",
            "value" : "2020-01-30T12:24:05.00Z"
        }, 
        {
            "name" : "type",
            "type" : "String",
            "value" : "fertigation"
        }
    ]
}

我需要将 sensor_type 字段转换为只有一个对象的数组,如下所示:

{
   "_id":"15_62",
   "medidas":[
      {
         "_id":"5e3419e468d01013eadb83dc",
         "marca":"Hortisis",
         "modelo":"Estacion",
         "fabricante":"Hortisis",
         "id_station":"15",
         "sensor_type":[
            {
               "name":"15",
               "type":"fertigation",
               "place":"interior",
               "img":"assets/img/contrast.png",
               "name_comun":"Temp. Suelo",
               "medida":"mS/cm"
            }
         ],
         "attrName":"15",
         "attrValue":0.33,
         "recvTimeTs":1580387045,
         "recvTime":"2020-01-30T12:24:05.00Z",
         "id_sensor_station_absolute":"15_62"
      }
   ]
}

如您所见,它正在格式化 sensor_type 字段 = 名称:值。

我正在使用 NODEJS 和猫鼬。

这是我的查询:(首先我搜索,排序,只显示第一个值,然后使用我给出格式的项目,问题是如果我输入“sensor_type”,我不知道如何告诉项目输入该格式: "$latest.attributes.name") 它只显示名称,我不知道如何以上述格式显示。

Datagreenhouse.aggregate([
        { "$match": { "id_sensor_station_absolute": { "$in": array3 } } }, // "id_station": { "$in": id_station },
        { "$sort": { "recvTime": -1 } },
        {
            "$group": {
                "_id": "$id_sensor_station_absolute",
                "latest": { "$first": "$$ROOT" },
            }
        },
        {
            "$project": {
                "_id": 1,
                "id_station": "$latest.id_station",
                //"id_sensor_station_absolute": "$id_sensor_station_absolute",
                "attrName": "$latest.attrName",
                "attrValue": "$latest.attrValue",
                "recvTimeTs": "$latest.recvTimeTs",
                "recvTime": "$latest.recvTime",
                "id_sensor_station_absolute": "$latest.id_sensor_station_absolute",
                "sensor_type": "$latest.attributes",


"name": { $arrayElemAt: ["$latest.attributes", 0] },
                "type": { $arrayElemAt: ["$latest.attributes", 1] },
                "place": { $arrayElemAt: ["$latest.attributes", 2] },
                "img": { $arrayElemAt: ["$latest.attributes", 1] },
                "name_comun": { $arrayElemAt: ["$latest.attributes", 4] },
                "medida": { $arrayElemAt: ["$latest.attributes", 3] },
                "interfaz": { $arrayElemAt: ["$latest.attributes", 6] },

            }
        }
    ], (err, DatagreenhouseRecuperado) => {
        if (err) return res.status(500).send({ message: 'Error al realizar la peticion' + err })
        if (!DatagreenhouseRecuperado) return res.status(404).send({ message: 'Error el usuario no existe' })
        res.status(200).send({ DatagreenhouseRecuperado })
    })

谢谢您的帮助。此致。

标签: mongodbmongooseaggregation-framework

解决方案


从 3.4.4 版本开始,MongoDB 引入了一个 magnific 运算符:$arrayToObject

该运算符允许我们将数组key:value对转换为对象。

句法

RAW DATA                           $map                        $arrayToObject
sensor_type : [                    sensor_type : [             sensor_type : {
  {                             \    {                      \   
    "name" : "manufacturer", ---->     k: "manufacturer", --->   
    "type" : "String",          /      v: "Hortisis"        /    "manufacturer" : "Hortisis"
    "value" : "Hortisis"                    
  }                                  }
]                                  ]                            }

db.datagreenhouses.aggregate([
  {
    "$match": {} // setup your match criteria
  },
  {
    "$sort": {
      "recvTime": -1
    }
  },
  {
    $group: {
      _id: "$id_sensor_station_absolute",
      medidas: {
        $push: {
          _id: "$_id",
          "marca": "Hortisis", // don't know where you get this value
          "modelo": "Estacion", // don't know where you get this value
          "id_station": "$id_station",
          "attrName": "$attrName",
          "attrValue": "$attrValue",
          "recvTimeTs": "$recvTimeTs",
          "recvTime": "$recvTime",
          "id_sensor_station_absolute": "$id_sensor_station_absolute",
          "sensor_type": {
            $arrayToObject: {
              $map: {
                input: "$sensor_type",
                in: {
                  k: "$$this.name",
                  v: "$$this.value"
                }
              }
            }
          }
        }
      }
    }
  }
])

Mongo游乐场


[
  {
    "_id": "15_62",
    "medidas": [
      {
        "_id": ObjectId("5e3419e468d01013eadb83dc"),
        "attrName": "15",
        "attrValue": 0.33,
        "id_sensor_station_absolute": "15_62",
        "id_station": "62",
        "marca": "Hortisis",
        "modelo": "Estacion",
        "recvTime": "2020-01-30T12:24:05.00Z",
        "recvTimeTs": 1.580387045e+09,
        "sensor_type": {
          "id": "15",
          "img": "assets/img/contrast.png",
          "manufacturer": "Hortisis",
          "medida": "mS/cm",
          "name_comun": "CE del medio",
          "place": "interior",
          "timestamp": "2020-01-30T12:24:05.00Z",
          "type": "fertigation"
        }
      }
    ]
  }
]

您需要做的就是使用易于处理的对象($unwindmedidas 字段,转换然后$group再次)将数据转换为所需的结果

注意:如果您的 MongoDB 是 3.4.4 之前的版本,请按照更新程序进行操作:

  1. 安装 MongoDB 3.4.4 或更新版本
  2. mongodump使用新版本 MongoBD制作
  3. 停止旧的 MongoBD
  4. 删除 /data 目录(进行备份)
  5. 启动新的 MongoDB 并运行mongorestore

推荐阅读