jjzjj

Mongodb 聚合与 mongoose 过滤器嵌入文档

coder 2023-11-07 原文

我正在使用 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 })
        })
    }

问候,谢谢。

编辑 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 中,它显示的是一个数据,而不是该对象的所有信息。如何添加其他字段?

最佳答案

基本上,所有代码都是正确的,您在查找中所做的是匹配所有传感器,sensor_types 数组中有一个名为“XX”的传感器。查找完成了它的工作,它返回所有匹配项,但这些数组有额外的文档。当您匹配子文档时,它不会为您过滤。

只需在 $project 中过滤它们,或者在您的 $addFields 中添加以下内容

"sensor.sensor_type": {
    "$filter": {
        "input": "$sensor.sensor_type",
        "as": "sensorType",
        "cond": { "$eq": ['$$sensorType.name', 33]}
    }
 }

您可以做的另一件事是更改 $lookup 以让 let 和管道在此管道内进行匹配并投影数据。这是更清洁和更好的方法。我也会在当天晚些时候用这个例子更新答案。

关于Mongodb 聚合与 mongoose 过滤器嵌入文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55972046/

有关Mongodb 聚合与 mongoose 过滤器嵌入文档的更多相关文章

  1. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

  2. Matlab imread()读到了什么 (浅显 当复习文档了) - 2

    matlab打开matlab,用最简单的imread方法读取一个图像clcclearimg_h=imread('hua.jpg');返回一个数组(矩阵),往往是a*b*cunit8类型解释一下这个三维数组的意思,行数、数和层数,unit8:指数据类型,无符号八位整形,可理解为0~2^8的数三个层数分别代表RGB三个通道图像rgb最常用的是24-位实现方法,即RGB每个通道有256色阶(2^8)。基于这样的24-位RGB模型的色彩空间可以表现256×256×256≈1670万色当imshow传入了一个二维数组,它将以灰度方式绘制;可以把图像拆分为rgb三层,可以以灰度的方式观察它figure(1

  3. ruby-on-rails - 在 Controller 中干净地处理多个过滤器(参数) - 2

    我有一个名为Post的类,我需要能够适应以下场景:如果用户选择了一个类别,则只显示该类别的帖子如果用户选择了一种类型,则只显示该类型的帖子如果用户选择了一个类别和类型,则只显示该类别中该类型的帖子如果用户没有选择任何内容,则显示所有帖子我想知道我的Controller是否不可避免地会因大量条件语句而显得粗糙...这是我解决此问题的错误方法-有谁知道我如何才能做到这一点?classPostsController 最佳答案 您最好遵循“胖模型,瘦Controller”的惯例,这意味着您应该将这种逻辑放在模型本身中。Post类应该能够报告

  4. ruby-on-rails - 如何处理 Grape 中特定操作的过滤器之前? - 2

    我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?

  5. ruby-on-rails - Rails 3 - 过滤器链暂停为 :authentication rendered or redirected - 2

    我仍然收到标题中的“错误”消息,但不知道如何解决。在ApplicationController中,classApplicationController在routes.rb#match'set_activity_account/:id/:value'=>'users#account_activity',:as=>:set_activity_account--thisdoesn'tworkaswell..resources:usersdomemberdoget:action_a,:action_bendcollectiondoget'account_activity'endend和User

  6. ruby-on-rails - ActiveAdmin 自定义选择过滤器下拉名称 - 2

    对于用户模型,我有一个过滤器来检查用户的预订状态,该状态由整数值(0、1或2)表示。UserActiveAdmin索引页上的过滤器是通过以下代码实现的:filter:booking_status,as::select然而,这会导致下拉选项为0、1或2。当管理员用户从下拉列表中选择它们时,我更愿意自己将它们命名为“未完成”、“待定”和“已确认”之类的名称。有没有办法在不改变booking_status在模型中的表示方式的情况下做到这一点? 最佳答案 假设booking_status是模型中的枚举字段,您可以使用:过滤器:booking

  7. Ruby 等同于 Sphinx 文档生成器? - 2

    Ruby有一些不错的文档生成器,例如Yard、rDoc,甚至Glyph。问题是Sphinx可以做网站、PDF、epub、LaTex等。它在重组文本中完成所有这些事情。在Ruby世界中有替​​代方案吗?也许是程序的组合?如果我也能使用Markdown就更好了。 最佳答案 自1.0版以来,Sphinx有了“域”的概念,它是从Python和/或C以外的语言标记代码实体(如方法调用、对象、函数等)的方法。有一个rubydomain,所以你可以只使用Sphinx本身。您唯一会缺少的(我认为)是Sphinx使用autodoc从源代码自动创建文档

  8. ruby - Rails Elasticsearch 聚合 - 2

    不知何故,我似乎无法获得包含我的聚合的响应...使用curl它按预期工作:HBZUMB01$curl-XPOST"http://localhost:9200/contents/_search"-d'{"size":0,"aggs":{"sport_count":{"value_count":{"field":"dwid"}}}}'我收到回复:{"took":4,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":90,"max_score":0.0,"hits":[]},"a

  9. ruby-on-rails - 在 irb 中阅读文档 - 2

    我怀念ipython的一件事是它有一个?为特定功能挖掘文档的运算符。我知道ruby​​有一个类似的命令行工具,但是我在irb中调用它非常不方便。ruby/irb有类似的东西吗? 最佳答案 Pry是IPython的Ruby版本,它支持?命令来查找有关方法的文档,但语法略有不同:pry(main)>?File.dirnameFrom:file.cinRubyCore(CMethod):Numberoflines:6visibility:publicsignature:dirname()Returnsallcomponentsofthef

  10. ruby - 使用 Nokogiri 和 Ruby 从 html 文档获取链接和 href 文本? - 2

    我正在尝试使用nokogirigem提取页面上的所有url及其链接文本,并将链接文本和url存储在散列中。FooBar我想回去{"Foo"=>"#foo","Bar"=>"#bar"} 最佳答案 这是一个单行:Hash[doc.xpath('//a[@href]').map{|link|[link.text.strip,link["href"]]}]#=>{"Foo"=>"#foo","Bar"=>"#bar"}拆分一点可以说更具可读性:h={}doc.xpath('//a[@href]').eachdo|link|h[link.t

随机推荐