$ elemMatch和$ in。查询文档数组

时间:2018-05-30 10:55:11

标签: mongodb mongoose mongodb-query

有一个集合(productList)和如下文档:

    {   "_id":"1",
        "product_name" : "Haier 240l",
        "version" : "1.0",
        "filterInfo" : [ 
            {
                "name" : "brand",
                "value" : "Haier"
            }, 
            {
                "name" : "energy_rating",
                "value" : "4 Star"
            }
         ]
    }
    {   "_id":"2",
        "product_name" : "Haier 310l",
        "version" : "1.0",
        "filterInfo" : [ 
            {
                "name" : "brand",
                "value" : "Haier"
            }, 
            {
                "name" : "energy_rating",
                "value" : "3 Star"
            }
         ]
    }

    {   "_id":"3",
        "product_name" : "Samsung 275l",
        "version" : "1.0",
        "filterInfo" : [ 
            {
                "name" : "brand",
                "value" : "Samsung"
            }, 
            {
                "name" : "energy_rating",
                "value" : "3 Star"
            }
         ]
    }
 {   "_id":"4",
        "product_name" : "Lg 254l",
        "version" : "1.0",
        "filterInfo" : [ 
            {
                "name" : "brand",
                "value" : "Lg"
            }, 
            {
                "name" : "energy_rating",
                "value" : "3 Star"
            }
         ]
    }

我想用(i)品牌获取所有文件:海尔 energy_rating:3
(ii)品牌:海尔品牌:三星 energy_rating:3
对于(i)我试过,使用下面的elemMatch查询:

db.productList.find({filterInfo: { $elemMatch: {'name':{$in:['brand','enery_rating']},'value':{$in:['Samsung','3 Star']}}}})

db.getCollection('productList').find({'filterInfo': {$elemMatch: { 'value':'Samsung', 'value' :'3 Star'} }  })

db.getCollection('productList').find({'filterInfo': {$elemMatch: {   $and:[ {'name':'brand', 'value' :'Samsung'}, {'name':'energy_rating', 'value':'3 Star' } ]} }    }) 

db.getCollection('productList').find({'filterInfo': {$elemMatch: {  'name':'brand', 'value' :'Samsung', 'name':'energy_rating', 'value':'3 Star'} }    })

但这些都没有正常工作。我在这里做了一些bascis错误(新手在这里)。

2 个答案:

答案 0 :(得分:0)

第一次查询

db.productList.find({
  "$and":[
    {"filterInfo":{"$elemMatch":{"name":"brand","value":"Haier"}}},
    {"filterInfo":{"$elemMatch":{"name":"energy_rating","value":"3 Star"}}}
  ]
})

您可以使用$all with $elemMatch简化第一个查询,以对数组执行查询。

db.productList.find({
  "filterInfo":{
    "$all":[
      {"$elemMatch":{"name":"brand","value":"Haier"}},
      {"$elemMatch":{"name":"energy_rating","value":"3 Star"}}
    ]
  }
})

第二次查询

db.productList.find({
  "$and":[
    {"$or":[
      {"filterInfo":{"$elemMatch":{"name":"brand","value":"Samsung"}}},
      {"filterInfo":{"$elemMatch":{"name":"brand","value":"Haier"}}}
    ]},
    {"filterInfo":{"$elemMatch":{"name":"energy_rating","value":"3 Star"}}}
  ]
})

答案 1 :(得分:0)

我想说,不需要$elemMatch

第一次查询

db.productList.find({
   $and:[
         {'filterInfo.value':'Haier'},
         {'filterInfo.value':'3 Star'}
        ]
});

第二次查询

db.productList.find({
   $and:[
         {'filterInfo.value':{
            $in:['Haier','Samsung']}
         },
         {'filterInfo.value':'3 Star'}
        ]
});

更多地关注MongoDB中的数据结构,以优化性能。 我不知道你的应用程序逻辑,但是有必要将所有这些数据保存在一个数组中。我不认为有必要保持数据简单,如 JSON 1 ,或者如果您具体关注filterInfo密钥可以设计为 JSON 2

JSON 1

{
    "_id" : "1",
    "product_name" : "Haier 240l",
    "version" : "1.0",
    "brand":"Haier",
    "energy_rating":"4 Star"
}

JSON 2

 {
        "_id" : "1",
        "product_name" : "Haier 240l",
        "version" : "1.0",
        "filterInfo": {
            "brand":"Haier",
            "energy_rating":"4 Star"
            }
 }