订单示例数据:
{
"total_goods_num" : 3,
"goods" : [
{
"amount" : 1,
"goods_code" : "100016079918",
"price" : { "$numberDecimal" : "5899.59" },
"wait_num" : 1,
"goods_id" : "1006"
},
{
"amount" : 2,
"goods_code" : "100009464821",
"price" : { "$numberDecimal" : "4798.37" },
"wait_num" : 2,
"goods_id" : "1005"
}
],
"created_at" : "2021-07-12 13:24:19",
"bill_no" : "D20210712174",
"userID" : "17333185253",
"updated_at" : "2021-07-12 14:43:58",
"address" : {
"province" : "安徽省",
"city" : "",
"area" : "",
"detail" : ""
},
"bill_status" : "1",
"pay_time" : "2021-07-12 13:23:48",
"total_money" : { "$numberDecimal" : "15496.33000" },
}
1】直接使用嵌套字段查询
1.1:这样的匹配结果,只要数据组中有包含查询条件的数据,就会返回文档数据
db.getCollection("bill").find({
'goods.goods_code': "100009464821"
})
2】只返回匹配的嵌套数组数据
2.1:可以用$elemMatch操作符 (从mongodb 2.2开始支持)
2.2:可以用$操作符(从mongodb 2.2开始支持)
---- 使用$elemMatch操作符
db.bill.find(
{
'goods.goods_code': "100009464821"
},
{
"goods": {$elemMatch:{"goods_code":"100009464821"}}
}
)
---- 使用$操作符
db.bill.find({'goods.goods_code': "100009464821"}, {_id: 0, 'goods.#39;: 1});
注意:
上面两个操作符,官方有这样的说明:the $elemMatch projection returns only the first matching element from the array.
也就是说,只会返回匹配到的第一个数据元素。(也可以通过下面的官方demo了解到)
================ 官方demo ==============
操作符说明:https://docs.mongodb.com/manual/reference/operator/projection/elemMatch/#proj._S_elemMatch
示例数据:
{
_id: 1,
zipcode: "63109",
students: [
{ name: "john", school: 102, age: 10 },
{ name: "jess", school: 102, age: 11 },
{ name: "jeff", school: 108, age: 15 }
]
}
{
_id: 2,
zipcode: "63110",
students: [
{ name: "ajax", school: 100, age: 7 },
{ name: "achilles", school: 100, age: 8 },
]
}
{
_id: 3,
zipcode: "63109",
students: [
{ name: "ajax", school: 100, age: 7 },
{ name: "achilles", school: 100, age: 8 },
]
}
{
_id: 4,
zipcode: "63109",
students: [
{ name: "barney", school: 102, age: 7 },
{ name: "ruth", school: 102, age: 16 },
]
}
db.schools.find(
{ zipcode: "63109" },
{ students: { $elemMatch: { school: 102 } } }
)
执行上面的SQL会得到下面的结果:
{ "_id" : 1, "students" : [ { "name" : "john", "school" : 102, "age" : 10 } ] }
{ "_id" : 3 }
{ "_id" : 4, "students" : [ { "name" : "barney", "school" : 102, "age" : 7 } ] }
注意:
- For the document with _id equal to 1, the students array contains multiple elements with the school field equal to 102. However, the $elemMatch projection returns only the first matching element from the array.
- The document with _id equal to 3 does not contain the students field in the result since no element in its students array matched the $elemMatch condition.
Mongodb3.2开始可以使用$filter对数组进行过滤:
db.schools.aggregate([
{$match: {zipcode: "63109", students: { $elemMatch: { school: 102 } }}},
{$project: {
students: {$filter: {
input: '$students',
as: 'student',
cond: {$eq: ['$student.school', 102]}
}},
_id: 1
}}
])
执行上面的SQL会得到下面的结果集:
{"_id" : 1, "students" : [{ "name" : "john", "school" : 102, "age" : 10 }, { name: "jess", school: 102, age: 11 }]}
{"_id" : 4, "students" : [{ "name" : "barney", "school" : 102, "age" : 7 },{ name: "ruth", school: 102, age: 16 }]}
注意:
$filter与$elemMatch和$相比,会把匹配到的所有数组数据都返回。而且排除了不符合条件条件的文档数据。