2013-08-08 14 views
5

Sto provando a creare una query mongo che restituirà risultati in cui tutti gli array hanno un elemento specifico impostato su false.Query Mongo - Array, trova solo dove tutti gli elementi corrispondono

Un record di dati di esempio: -

images: [ 
    { 
     id: ObjectId("516bef7fc05e877b31000000"), 
     primary: true 
    }, 
    { 
     id: ObjectId("516bef2ac05e879622000000"), 
     primary: false 
    }, 
    { 
     id: ObjectId("516beeb7c05e879e2a000000"), 
     primary: false 
    } 
], 
name: "test", 
etc: "etc" 

solo desidero trovare i documenti in cui tutti i campi principali sono impostati su false però normalmente (usando nessun selettori query o elemMatch) Mongo restituirà questo documento perché almeno 1 degli elementi dell'array corrispondono.

Come farei a mongo restituire solo i documenti in cui corrispondono tutti i miei parametri di ricerca?

Molte grazie.

risposta

4

Si può fare questo con il quadro di aggregazione abbastanza facilmente:

db.so.aggregate([ 
    { $unwind: "$images" }, 
    { $group: { 
     _id: '$_id', 
     all: { $sum: 1 }, 
     all_primary: { $sum: { $cond: [ { $eq: [ '$images.primary', true ] }, 1, 0 ] } }, 
     images: { $push: '$images' }, 
     name: { $first: '$name' }, 
     etc: { $first: '$etc' }, 
    } }, 
    { $project: { 
     _id: 1, 
     images: 1, 
     name: 1, 
     etc: 1, 
     same: { $cond: [ { $eq: [ '$all', '$all_primary' ] }, 1, 0 ] } 
    } }, 
    { $match: { 'same' : 1 } } 
]); 

Con questo come input:

{ 
    "_id" : ObjectId("5203730bf8eaa52a846ebc3e"), 
    "images" : [ 
     { 
      "id" : ObjectId("516bef7fc05e877b31000000"), 
      "primary" : true 
     }, 
     { 
      "id" : ObjectId("516bef2ac05e879622010000"), 
      "primary" : true 
     }, 
     { 
      "id" : ObjectId("516beeb7c05e879e2a000010"), 
      "primary" : true 
     } 
    ], 
    "name" : "Derick", 
    "Etc" : true 
} 
{ 
    "_id" : ObjectId("52037315f8eaa52a846ebc3f"), 
    "images" : [ 
     { 
      "id" : ObjectId("516bef7fc05e877b31000000"), 
      "primary" : true 
     }, 
     { 
      "id" : ObjectId("516bef2ac05e879622010000"), 
      "primary" : true 
     }, 
     { 
      "id" : ObjectId("516beeb7c05e879e2a000020"), 
      "primary" : false 
     } 
    ], 
    "name" : "James", 
    "Etc" : true 
} 
{ 
    "_id" : ObjectId("520373621a78238235b6ffbf"), 
    "images" : [ 
     { 
      "id" : ObjectId("516bef7fc05e877b31000000"), 
      "primary" : true 
     }, 
     { 
      "id" : ObjectId("516bef2ac05e879622010000"), 
      "primary" : true 
     }, 
     { 
      "id" : ObjectId("516beeb7c05e879e2a000020"), 
      "primary" : false 
     } 
    ], 
    "name" : "James", 
    "etc" : true 
} 
{ 
    "_id" : ObjectId("5203736b1a78238235b6ffc0"), 
    "images" : [ 
     { 
      "id" : ObjectId("516bef7fc05e877b31000000"), 
      "primary" : true 
     }, 
     { 
      "id" : ObjectId("516bef2ac05e879622010000"), 
      "primary" : true 
     }, 
     { 
      "id" : ObjectId("516beeb7c05e879e2a000020"), 
      "primary" : true 
     } 
    ], 
    "name" : "James", 
    "etc" : true 
} 

Questo uscite:

{ 
    "result" : [ 
     { 
      "_id" : ObjectId("5203736b1a78238235b6ffc0"), 
      "images" : [ 
       { 
        "id" : ObjectId("516bef7fc05e877b31000000"), 
        "primary" : true 
       }, 
       { 
        "id" : ObjectId("516bef2ac05e879622010000"), 
        "primary" : true 
       }, 
       { 
        "id" : ObjectId("516beeb7c05e879e2a000020"), 
        "primary" : true 
       } 
      ], 
      "name" : "James", 
      "etc" : true, 
      "same" : 1 
     }, 
     { 
      "_id" : ObjectId("5203730bf8eaa52a846ebc3e"), 
      "images" : [ 
       { 
        "id" : ObjectId("516bef7fc05e877b31000000"), 
        "primary" : true 
       }, 
       { 
        "id" : ObjectId("516bef2ac05e879622010000"), 
        "primary" : true 
       }, 
       { 
        "id" : ObjectId("516beeb7c05e879e2a000010"), 
        "primary" : true 
       } 
      ], 
      "name" : "Derick", 
      "etc" : null, 
      "same" : 1 
     } 
    ], 
    "ok" : 1 
} 
+0

Grazie, Derick, funziona bene. – user1954882

-1

Presumendo immagini è un documento è possibile utilizzare (dalla shell):

db.images.find ({ 'primaria': 'false'})

Se le immagini è un oggetto:

db.mydoc.find ({ 'immagini': { 'primaria': 'false'}})

+0

'db.articles.find ({'images.primary': false})' fa quello che descrivo sopra, restituirà il documento se solo uno degli elementi dell'array corrisponde. 'db.articles.find ({'images': {'primary': false}})' non restituisce nulla. – user1954882

3

Non sarebbe molto più semplice per escludere tutti i documenti in cui images ha primario: vero e proprio elemento?

{ "images" : 
{ "$not" : 
    {"$elemMatch" : { "primary" : true }} 
} 
} 

Naturalmente, questo è applicabile solo a un campo nidificato booleano, come in questo caso.

Problemi correlati