我正在使用NodeJS和mongoose,并汇总了两个集合:
集合1(工作站)
/* 1 */
{
"_id" : ObjectId("xxx"),
"marca" : "x",
"modelo" : "xx",
"fabricante" : "x",
"id_station" : [
191,
457
],
"sensor_type" : [
{
"name" : 2,
"type" : "clima",
"place" : "interior",
"img" : "assets/img/hum.png",
"name_comun" : "Hum. Relativa",
"medida" : "%",
"interfaz" : ""
},
{
"name" : 3,
"type" : "clima",
"place" : "interior",
"img" : "assets/img/hum.png",
"name_comun" : "Hum. Relativa",
"medida" : "%",
"interfaz" : ""
}
]
}
/* 2 */
{
"_id" : ObjectId("5ccacc61a0160f16c50f5a1b"),
"marca" : "y",
"modelo" : "yy",
"fabricante" : "y",
"id_station" : [
999
],
"sensor_type" : [
{
"name" : 2,
"type" : "clima",
"place" : "interior",
"img" : "assets/img/hum.png",
"name_comun" : "Temperatura",
"medida" : "%",
"interfaz" : ""
},
{
"name" : 3,
"type" : "clima",
"place" : "interior",
"img" : "assets/img/hum.png",
"name_comun" : "Hum. Relativa",
"medida" : "%",
"interfaz" : ""
}
]
}
集合2(度量):
/* 1 */
{
"_id" : ObjectId("5ccc29612bda12f1f16ac600"),
"id_station" : "191",
"attrName" : 2,
"attrType" : "float",
"attrValue" : 21,
"recvTimeTs" : 1554134471,
"recvTime" : "2019-04-01T16:01:11.000Z"
}
/* 2 */
{
"_id" : ObjectId("5ccc2a852bda12f1f16ac6b1"),
"id_station" : "191",
"attrName" : 3,
"attrType" : "float",
"attrValue" : 2222,
"recvTimeTs" : 1554134499,
"recvTime" : "2019-09-01T16:01:11.000Z"
}
/* 3 */
{
"_id" : ObjectId("5ccc3a7d2bda12f1f16acc34"),
"id_station" : "999",
"attrName" : 33,
"attrType" : "float",
"attrValue" : 2222,
"recvTimeTs" : 1554134499,
"recvTime" : "2019-09-01T16:01:11.000Z"
}
完成聚合后,将显示完全嵌入到集合中的文档,而我只需要显示与attrname匹配的文档即可。
如何在嵌入式文档中执行搜索?是否可以仅显示该信息?
我需要sensor_type仅显示名称信息:33,因为当嵌入式文档显示该数据并且是错误的时,它是2的真实值。
有错误的代码:
{
"DatagreenhouseRecuperado":[
{
"_id":33,
"medidas":[
{
"_id":"5ccacc61a0160f16c50f5a1b",
"marca":"Metos",
"modelo":"Estacion",
"fabricante":"Metos",
"id_station":[
999
],
"sensor_type":[
{
"name":2,
"type":"clima",
"place":"interior",
"img":"assets/img/hum.png",
"name_comun":"Temperatura",
"medida":"%",
"interfaz":""
},
{
"name":33,
"type":"clima",
"place":"interior",
"img":"assets/img/hum.png",
"name_comun":"Hum. Relativa",
"medida":"%",
"interfaz":""
}
],
"attrName":33,
"attrValue":8888,
"recvTimeTs":1588524826,
"recvTime":"2020-05-03T18:53:46"
}
],
"count":1
}
]
}
目标是:
{
"DatagreenhouseRecuperado":[
{
"_id":33,
"medidas":[
{
"_id":"5ccacc61a0160f16c50f5a1b",
"marca":"Metos",
"modelo":"Estacion",
"fabricante":"Metos",
"id_station":[
999
],
"sensor_type":[
{
"name":33,
"type":"clima",
"place":"interior",
"img":"assets/img/hum.png",
"name_comun":"Hum. Relativa",
"medida":"%",
"interfaz":""
}
],
"attrName":33,
"attrValue":8888,
"recvTimeTs":1588524826,
"recvTime":"2020-05-03T18:53:46"
}
],
"count":1
}
]
}
代码:
function getDataSensorGreenhouseLastDataPruebas(req, res) {
var array = req.params.nombresensores;
var id_station = array.split(',');
var array2 = req.params.sensores;
//var sensor = array2.split(',');
// var id_station = req.params.id_station;
console.log('id_station: ' + id_station);
Datagreenhouse.aggregate([
{ "$match": { "id_station": { "$in": [191, 999] }, "attrName": { "$in": [2, 33] } } },
{ "$sort": { "recvTime": -1 } },
{
"$group": {
"_id": "$id_station",
"latest": { "$first": "$$ROOT" },
}
},
{
"$project": {
"_id": 1,
"id_station": "$latest.id_station",
"attrName": "$latest.attrName",
"attrValue": "$latest.attrValue",
"recvTimeTs": "$latest.recvTimeTs",
"recvTime": "$latest.recvTime"
}
},
{
"$lookup": {
"from": "station_types",
"localField": "id_station", // local field in measurements collection
"foreignField": "id_station", //foreign field from sensors collection
"as": "sensor"
}
},
{ "$unwind": "$sensor" },
// { "$match": { "sensor.sensor_type.name": 2 } },
{
"$addFields": {
"sensor.attrName": "$attrName", // Add attrName to the sensors
"sensor.attrValue": "$attrValue", // Add attrValue to the sensors
"sensor.recvTimeTs": "$recvTimeTs",
"sensor.recvTime": "$recvTime"
}
},
{
"$group": {
"_id": "$id_station", // Group by time
"medidas": { "$push": "$sensor" }, // Collect measurements
"count": { "$sum": 1 } // Count measurements
}
},
], (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' })
console.log('Ordenado: ' + JSON.stringify(DatagreenhouseRecuperado));
/*DatagreenhouseRecuperado.sort(function(a, b) {
return (a._id - b._id)
})*/
res.status(200).send({ DatagreenhouseRecuperado })
})
}
问候,谢谢。
EDIT 01 解决方案
您好,这是对代码的改编:
{
"$addFields": {
"sensor.attrValue": "$attrValue", // Add attrValue to the sensors
"sensor.attrName": "$attrName", // Add attrValue to the sensors
"sensor.recvTimeTs": "$recvTimeTs", // Add attrName to the sensors
"sensor.pruebas": "$name_comun", // Add attrName to the sensors
"sensor.sensor_type": {
$filter: {
input: '$sensor.sensor_type',
as: 'shape',
cond: { $eq: ['$$shape.name', '$attrName'] },
}
}
}
},
问题在于在sensor_type中它显示数据,而不是该对象的所有信息。如何添加其他字段?
答案 0 :(得分:0)
基本上,所有代码都是正确的,您在该查找中所做的与所有传感器匹配,sensor_types数组内部具有一个名称为“ XX”的传感器。查找完成了它的工作,它返回所有匹配项,但是这些数组还有其他文档。当您匹配子文档时,它不会为您过滤。
只需在$ project中过滤它们,或在$ addFields中添加以下内容
"sensor.sensor_type": {
"$filter": {
"input": "$sensor.sensor_type",
"as": "sensorType",
"cond": { "$eq": ['$$sensorType.name', 33]}
}
}
您可以做的另一件事是更改$ lookup以使let和管道在该管道内进行匹配并投影数据。这是一种更干净,更好的方法。当天晚些时候,我还将通过此示例更新答案。