如何使用多个条件查找查询在 MongoDB 中指定字段?
Posted
技术标签:
【中文标题】如何使用多个条件查找查询在 MongoDB 中指定字段?【英文标题】:How to specify fields in MongoDB with multiple condition find query? 【发布时间】:2019-03-15 09:32:00 【问题描述】:这是单个文档:
_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"
]
我正在尝试仅选择 John's BMW 的“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"
]
有什么想法吗?
【问题讨论】:
【参考方案1】:为什么它不起作用?
"firstName": "John", "cars.carName": "BMW"
表示“名字是 john,并且汽车数组中至少有一个条目,其中 carName 是“BMW””。但它返回完整的文档,没有过滤数组。
"_id": 0, "cars.carColor": 1
不投影_id,而是投影cars数组所有条目的carColor。
解决方案
事实上,使用 find 和 projection 方法并不能完全达到您想要的效果。你可以做的更好的是像这样添加$ 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"
])
【讨论】:
【参考方案2】:db.persons.find(
firstName: 'john',
cars:
$elemMatch:
carName: 'BMW'
,
'cars.$': 1
)
【讨论】:
【参考方案3】:如果您知道数组中的“BMW”值不超过一个,那么这是一种使用单个$project
阶段获取结果的方法:
db.getCollection('collection').aggregate([
$match:
"firstName": "john"
/* for performance reasons, you may want to include the following line which, however, is not required */
/* this makes sense if you have lots of "john"s with different sets of cars in your database */
, "cars.carName": "BMW" // this will use an index on "cars.carName" if available
,
$project:
_id: 0, // do not return the _id field
color:
$reduce: // transform the filtered input array
"input":
$filter: // remove all non-"BMW" cars from the "cars" array
input: "$cars",
as: "car",
cond: $eq: [ "$$car.carName", "BMW" ]
,
"initialValue": null,
"in": "$$this.carColor" // just return the color value, nothing else
])
【讨论】:
以上是关于如何使用多个条件查找查询在 MongoDB 中指定字段?的主要内容,如果未能解决你的问题,请参考以下文章
mongodb更新查询删除命令中指定的字段以外的所有数组字段