如何在不指定父字段的情况下直接查询嵌套字段? [英] How to directly query nested field without specify parent field?

查看:41
本文介绍了如何在不指定父字段的情况下直接查询嵌套字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 mongodb 中有接下来的 3 个文档:

I have next 3 documents in mongodb:

文档 1:

{
    "name": "device1",
    "camera": {
        "number": 3
    }
}

文档 2:

{
    "name": "device2",
    "camera": {
        "number": 1
    }
}

文档 3:

{
    "name": "device3",
    "wifi": {
        "number": 2
    }
}

我的目标是找到所有模块编号>的设备.1、模块可能是camerawifi或其他.

My aim is to find all devices which modules' number > 1, the module maybe camera, wifi or others.

我知道我可以使用 next 来获取设备:

I know I can use next to get the device:

> db.devices.find({"camera.number":{$gt:1}})
{ "_id" : ObjectId("5f436a3df716cb47d319245e"), "name" : "device1", "camera" : { "number" : 3 } }
> db.devices.find({"wifi.number":{$gt:1}})
{ "_id" : ObjectId("5f436a58f716cb47d3192460"), "name" : "device3", "wifi" : { "number" : 2 } }

但看起来我不得不添加类似module.number"的东西;在查询中,您知道也许我有很多模块,那么使用 camera.numberwifi.numberothermodule.number 查找所有匹配的设备.如果可能的话,我可以用一些魔法来直接获取具有任何模块编号"的设备.1",我的意思是不需要指定父字段?

But it looks I had to add something like "module.number" in query, you know maybe I have a lots of modules, then not so efficient to use camera.number, wifi.number & othermodule.number to find all matched devices. If possible I can have something magic to directly get the device which "has any module's number > 1", I mean no need to specify the parent field?

推荐答案

我不认为 find() 方法可行,但您可以尝试 aggregate() 方法,

I don't think it is possible with find() method but you can try aggregate() method,

  • $addFields will add device field, which convert $$ROOT object to array in k and v format using $objectToArray
  • $match you can match device.v.number to your number
  • $project to hide device field
db.devices.aggregate([
  { $addFields: { device: { $objectToArray: "$$ROOT" } } },
  { $match: { "device.v.number": { $gt: 1 } } },
  { $project: { device: 0 } }
])

游乐场

aggregate() 方法的另一种可能方法,

Another Possible Way with aggregate() method,

  • 匹配$expr
  • $reduce 将输入 $$ROOT as $objectToArray 并在 in 内部使用 $ifNull 然后 $add 初始值中的数字,否则添加 0.
  • match with $expr
  • $reduce will input $$ROOT as $objectToArray and inside in checks condition if number is null using $ifNull then $add number in initialValue otherwise add 0.
db.collection.aggregate([
  {
    $match: {
      $expr: {
        $gt: [
          {
            $reduce: {
              input: { $objectToArray: "$$ROOT" },
              initialValue: 0,
              in: { $add: ["$$value", { $ifNull: ["$$this.v.number", 0] }] }
            }
          },
          1 // add your search number
        ]
      }
    }
  }
])

游乐场

这篇关于如何在不指定父字段的情况下直接查询嵌套字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆