arrays - 如何在MongoDB中指定字段进行多条件查找查询?

标签 arrays database mongodb mongoose mongodb-query

这是单个文档:

{
   _id: "...",
   firstName: "john",
   lastName:"Doe",
   cars: [
       {
           "_id": "...",
           "carName": "BMW",
           "carModel": "330",
           "carColor": "silver"
       },
       {
           "_id": "...",
           "carName": "Lexus",
           "carModel": "IS300",
           "carColor": "white"
       },
       {
           "_id": "...",
           "carName": "LADA",
           "carModel": "2106",
           "carColor": "blue"
       }
   ]
}

我试图仅选择约翰的宝马的“carColor”。 像这样的事情:

db.persons.findOne(
        { "firstName": "John", "cars.carName": "BMW" },
        { "_id": 0, "cars.$.carColor": 1 }
      );

但是这个查询返回完整的对象,如下所示:

{
    cars: [
      {
         "_id": "...",
         "carName": "BMW",
         "carModel": "330",
         "carColor": "silver"
      }
}

我已经尝试了不带 .$ 的不同查询。符号:

db.persons.findOne(
            { "firstName": "John", "cars.carName": "BMW" },
            { "_id": 0, "cars.carColor": 1 }
          );

此版本仅返回“carColor”属性,但不过滤“carName”。 像这样:

{
   cars: [
       {
          "carColor": "silver"
       },
       {
          "carColor": "white"
       },
       {
          "carColor": "blue"
       }
   ]
}

有什么想法吗?

最佳答案

为什么不起作用?

{"firstName": "John", "cars.carName": "BMW"}

表示“名字为 john,且 cars 数组中至少有一个条目的 carName 为“BMW””。但它返回完整的文档,没有过滤数组。

{ "_id": 0, "cars.carColor": 1 }

不投影 _id,而是投影 cars 数组所有条目的 carColor。

解决方案

事实上,使用查找和投影方法并不能完全达到您想要的效果。您可以做得更好的是添加 $ projection operator像这样:

db.collection.find({
  firstName: "john",
  "cars.carName": "BMW"
},
{
  _id: 0,
      "cars.$": 1
    })

**RESULT**

[
  {
    "cars": [
      {
        "_id": "...",
        "carColor": "silver",
        "carModel": "330",
        "carName": "BMW"
      }
    ]
  }
]

但是这种方法有缺点:

  • 您可以获得整个数组条目,而不仅仅是您想要/需要的颜色
  • 它仅返回第一个匹配条目:如果 john 有 2 辆 BMW,则仅返回一辆。

更好的解决方案

幸运的是,MongoDB 提供了另一种方法来实现这一点,即聚合框架,并且 $filter运算符:

db.collection.aggregate([
  {
    $match: {
      firstName: "john"
    }
  },
  {
    $project: {
      cars: {
        $filter: {
          input: "$cars",
          as: "cars",
          cond: {
            $eq: [
              "$$cars.carName",
              "BMW"
            ]
          }
        }
      }
    }
  },
  {
    $project: {
      _id: 0,
      "colors": "$cars.carColor"
    }
  }
])

You can try it here.

编辑:其他解决方案

你也可以尝试这个,通过放松/小组阶段:

db.collection.aggregate([
  {
    $match: {
      firstName: "john"
    }
  },
  {
    $unwind: "$cars"
  },
  {
    $match: {
      "cars.carName": "BMW"
    }
  },
  {
    $group: {
      "_id": null,
      colors: {
        $push: "$cars.carColor"
      }
    }
  }
])

关于arrays - 如何在MongoDB中指定字段进行多条件查找查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52740767/

相关文章:

node.js - 如何避免在 MongoDB 中使用 db.insertMany() 在集合中插入重复值?

javascript - 从两个数组生成 JSON

python - 如何堆叠 'numpy masked array' 和 'numpy array'

java - 如何实例化一个通用集合数组?

java - 如何从 JDBC 方法返回多行?

linux - MongoDB,非root的Ubuntu用户,PID文件存放在/var/run/mongodb

ios - 获取单个数组项

database - 在 2 个网络服务之间同步 postgres 数据库表

database - 如何更新 oracle 中一列的所有行,起始值为 500 并在 oracle 中递增

javascript - $lookup 深度嵌套对象