MongoDB之数组字段查询(mongodb查询数组里面的值)

订单示例数据:

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

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注