仅显示在 mongodb 中的数组中找到的元素

Show only an element found in an array in mongodb

我有这个collection:

/* 1 */
{
    "_id" : ObjectId("553e316e39108e802a1edeb9"),
    "coleccion" : "aplicaciones",
    "nombre" : "otra aplicacionn",
    "descripcion" : "w aplicacion",
    "tipo" : "privada",
    "campoId" : [ 
        {
            "id" : "1430230303",
            "id_campo" : "553bffed39108e346ccff7ab",
            "orden" : "25",
            "obligatorio" : "0"
        }, 
        {
            "id" : "1430233750",
            "id_campo" : "553bffca39108eb163cff7aa"
        }, 
        {
            "id" : "1430233753",
            "id_campo" : "553c001139108ebc63cff7aa",
            "orden" : "47",
            "estado" : "1"
        }
    ]
}

/* 2 */
{
    "_id" : ObjectId("553ce99a39108e2b7c1edeb9"),
    "coleccion" : "aplicaciones",
    "nombre" : "Mascotas",
    "descripcion" : "Censo de mascotas",
    "tipo" : "publica",
    "campoId" : [ 
        {
            "id" : "1430230465",
            "id_campo" : "553bffed39108e346ccff7ab",
            "orden" : "19",
            "obligatorio" : "0"
        }, 
        {
            "id" : "1430231597",
            "id_campo" : "553bffca39108eb163cff7aa",
            "estado" : "1",
            "obligatorio" : "1"
        }, 
        {
            "id" : "1430419469",
            "id_campo" : "554277d839108e6a5835c3e0",
            "orden" : "39",
            "obligatorio" : "0"
        }, 
        {
            "id" : "1430423643",
            "id_campo" : "553c001139108ebc63cff7aa",
            "orden" : "64",
            "obligatorio" : "1"
        }
    ]
}

我想像这样在数组中找到特定元素:

"obligatorio" : "1"

正在搜索字段:

"id" : "1430231597"

我试过:

db.getCollection('aplicaciones').find({campoId:{$elemMatch:{"id":"1430231597"}}},{"campoId.$.obligatorio":1,_id:0})

但我明白了

{
"campoId" : [ 
    {
        "id" : "1430231597",
        "id_campo" : "553bffca39108eb163cff7aa",
        "estado" : "1",
        "obligatorio" : "1"
    }
]

}

如何使结果只是“obligatiorio”字段的值?

您可以使用 "aggregation" 执行此操作。

db.aplicaciones.aggregate(
    [   
        { "$match": { "campoId.id": "1430231597" }},
        { "$unwind": "$campoId" }, 
        { "$match": { "campoId.id":"1430231597" }}, 
        { "$project": { "obligatorio": "$campoId.obligatorio", "_id":0 }}
    ]
)

但最好的方法是使用 $setDifference and the $map 运算符,因为 $unwind 可以是 "expensive"

db.aplicaciones.aggregate([ 
    { "$match": { "campoId.obligatorio": "1" }}, 
    { "$project": { "campoId": { 
        "$setDifference": [ 
            { "$map": { 
                "input": "$campoId",
                "as": "cp", 
                "in": { 
                    "$cond": [{ 
                        "$and": [ 
                            { "$eq": ["$$cp.obligatorio", "1" ]},
                            { "$eq": [ "$$cp.id", "1430231597" ]}  
                        ]}, 
                        "$$cp", 
                        false
                    ]
                }}
            }, 
            [false]
       ]}
    }}
])

产生:

{
        "_id" : ObjectId("553ce99a39108e2b7c1edeb9"),
        "campoId" : [
                {
                        "id" : "1430231597",
                        "id_campo" : "553bffca39108eb163cff7aa",
                        "estado" : "1",
                        "obligatorio" : "1"
                }
        ]
}