Mongodb 如何直接查询嵌套字段而不指定父字段?

Mongodb 如何直接查询嵌套字段而不指定父字段?,mongodb,mongodb-query,Mongodb,Mongodb Query,我在mongodb中有以下3个文档: 文件1: 文件2: 文件3: 我的目标是找到所有模块编号>1的设备,模块可能是摄像头、wifi或其他设备 我知道我可以使用next获取设备: > db.devices.find({"camera.number":{$gt:1}}) { "_id" : ObjectId("5f436a3df716cb47d319245e"), "name" : "device1&q

我在mongodb中有以下3个文档:

文件1:

文件2:

文件3:

我的目标是找到所有模块编号>1的设备,模块可能是摄像头、wifi或其他设备

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

> 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.number、wifi.number和othermodule.number查找所有匹配设备的效率不高。如果可能的话,我可以用一些神奇的方法直接获取任何模块编号大于1的设备,我的意思是不需要指定父字段?

简单,只需更改您的模式即可


很简单,只需更改您的模式


我认为用find方法是不可能的,但你可以试试这个方法

将添加设备字段,该字段使用将$$ROOT对象转换为k和v格式的数组 您可以将device.v.number与您的号码匹配 隐藏设备字段的步骤 另一种可能的方法是聚合法

匹配 将$$ROOT作为$objectToArray输入,如果数字为空,则在检查条件中使用$add number in initialValue,否则添加0。
我认为用find方法是不可能的,但你可以试试这个方法

将添加设备字段,该字段使用将$$ROOT对象转换为k和v格式的数组 您可以将device.v.number与您的号码匹配 隐藏设备字段的步骤 另一种可能的方法是聚合法

匹配 将$$ROOT作为$objectToArray输入,如果数字为空,则在检查条件中使用$add number in initialValue,否则添加0。
mongodb新手,请允许我了解一下,很快就会回来。好的,添加了参考链接管道。{$addFields:{device:{$objectToArray:$$ROOT}}}会带来任何效率问题吗?将文档转换为k-v并将设备添加为字段?我想与使用预定义的k-v(如前面提到的另一个答案)相比,使用此选项是一种折衷,我将使用我自己的真实数据集尝试其性能,感谢您提供的信息。$addFields将添加一个新字段,该字段由当前文档的所有根字段生成,所以可能需要更多的内存,我添加了另一个只匹配的解决方案,它比第一个查询更好,您可以使用新的mongodb检查两个查询的效率差异,让我了解一下,很快就会回来。好的,添加了参考链接管道。will{$addFields:{device:{$objectToArray:$$ROOT}带来效率问题吗?将文档转换为k-v并将设备添加为字段?我想与使用预定义的k-v(如前面提到的另一个答案)相比,使用此选项是一种折衷,我将使用我自己的真实数据集尝试其性能,感谢您提供的信息。$addFields将添加一个新字段,该字段由当前文档的所有根字段生成,所以可能会占用更多的内存,我添加了另一个解决方案,只匹配它比第一个查询要好,您可以使用
{
    "name": "device2",
    "camera": {
        "number": 1
    }
}
{
    "name": "device3",
    "wifi": {
        "number": 2
    }
}
> 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 } }
  {
    "name": "device1",
    "modules": [
      {
        "k": "camera",
        "v": 3
      }
    ]
  },
  {
    "name": "device2",
    "modules": [
      {
        "k": "wifi",
        "v": 3
      },
      {
        "k": "camera",
        "v": 2
      }
    ]
  },
  {
    "name": "device3",
    "modules": [
      {
        "k": "wifi",
        "v": 2
      }
    ]
  }

db.collection.find({"modules.v": 3})
db.devices.aggregate([
  { $addFields: { device: { $objectToArray: "$$ROOT" } } },
  { $match: { "device.v.number": { $gt: 1 } } },
  { $project: { device: 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
        ]
      }
    }
  }
])