订单示例数据:
{ "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和$相比,会把匹配到的所有数组数据都返回。而且排除了不符合条件条件的文档数据。