Mongodb搜索嵌入式文档。

时间:2016-11-14 12:09:31

标签: mongodb mongodb-query pymongo aggregation-framework

mongodb集合的结构是这样的。
 收集用户

{
"name":"sufaid",
"age":"22",
"address":"zzzz",
"product":[{"id":1,"name":"A"},
            {"id":6,"name":"N"},
            {"id":3,"name":"D"},
            {"id":7,"name":"q"},
        ]
}  

我需要找到产品ID “3”

的用户

输出应该是这样的

{
    "name":"sufaid",
    "age":"22",
    "address":"zzzz",
    "product":{"id":3,"name":"D"}
    } 
  

注意:不使用$ unwind和投影,例如“product。$”

使用pymongo时出现错误

“product。$”  还有其他选择吗???

3 个答案:

答案 0 :(得分:4)

使用$elemMatchhttps://docs.mongodb.com/manual/reference/operator/projection/elemMatch/

您的查询:

db.User.find({},{name:1,age:1,address:1,product:{$elemMatch:{id:3}}})

db.User.find({},{product:{$elemMatch:{id:3}}})

o/p:    { 
    "name" : "sufaid", 
    "age" : "22", 
    "address" : "zzzz", 
    "product" : [
        {
            "id" : 3.0, 
            "name" : "D"
        }
    ]

}

您需要进行汇总:

db.User.aggregate([
{$unwind:'$product'},
{$match:{'product.id':3}},
{$project:{_id:0,name:1,age:1,aaddress:1,product:1}}
])

O / P:

    { 
    "name" : "sufaid", 
    "age" : "22", 
    "address" : "zzzz", 
    "product" : {
        "id" : 3.0, 
        "name" : "D"
    }
}

这将准确给出您在问题中指出的内容。

答案 1 :(得分:2)

您可以使用聚合框架,其中包含大量可供您使用的运算符,尤其是您需要 $filter $arrayElemAt $project 管道中的strong>运算符。

例如,您可以通过运行以下管道将product字段作为嵌入文档返回:

db.user.aggregate([
    { "$match": { "product.id": 3 } },
    {
        "$project": {
            "name": 1,
            "age": 1,
            "address": 1,
            "product": {
                "$arrayElemAt": [
                    {
                        "$filter": {
                            "input": "$product",
                            "as": "item",
                            "cond": { "$eq": [ "$$item.id", 3 ] }
                        }
                    },
                    0
                ]
            }
        }
    }
])

示例输出

{
    "_id" : ObjectId("5829ac89628123dcf8a64b7a"),
    "name" : "sufaid",
    "age" : "22",
    "address" : "zzzz",
    "product" : {
        "id" : 3,
        "name" : "D"
    }
}

如果您只需要过滤数组的输出,请跳过 $arrayElemAt 表达式并仅使用 $filter

db.user.aggregate([
    { "$match": { "product.id": 3 } },
    {
        "$project": {
            "name": 1,
            "age": 1,
            "address": 1,
            "product": {
                "$filter": {
                    "input": "$product",
                    "as": "item",
                    "cond": { "$eq": [ "$$item.id", 3 ] }
                }
            }
        }
    }
])

示例输出

{
    "_id" : ObjectId("5829ac89628123dcf8a64b7a"),
    "name" : "sufaid",
    "age" : "22",
    "address" : "zzzz",
    "product" : [
        { "id" : 3, "name" : "D" }
    ]
}

答案 2 :(得分:0)

db.User.find({},{product:{$elemMatch:{id:3}}})

够了