2013-08-08 22 views
5

Próbuję utworzyć zapytanie mongo, które zwróci wyniki, gdzie wszystkie tablice mają określony element ustawiony na false.Mongo - zapytanie tablicowe, tylko tam, gdzie wszystkie elementy pasują do

Rekord przykład dane: -

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

Żałuję tylko, aby znaleźć dokumenty, w których wszystkie pola pierwotne są ustawione na false jednak normalnie (używając żadnych selektorów zapytań lub elemMatch) Mongo powróci tego dokumentu, ponieważ co najmniej 1 elementów tablicy pasują.

Jak utworzyć mongo tylko zwracać dokumenty, jeśli wszystkie pasują do moich parametrów wyszukiwania?

Wielkie dzięki.

Odpowiedz

4

można to zrobić z ramami agregacji dość łatwo:

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 } } 
]); 

Mając to na wejściu:

{ 
    "_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 
} 

This Wyjścia:

{ 
    "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

Dziękuję Derick, że działa dobrze. – user1954882

-1

Zakładając obrazów jest dokumentem można użyć (od powłoki):

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

Jeśli obrazy to obiekt:

db.mydoc.find ({ 'zdjęcia': { 'podstawowej': 'false'}})

+0

'db.articles.find ({'images.primary': false})' robi to, co opisałem powyżej, zwróci dokument, jeśli tylko jeden z elementów tablicy pasuje do siebie. 'db.articles.find ({'images': {'primary': false}})' nic nie zwraca. – user1954882

3

nie byłoby znacznie prostsze, aby wykluczyć wszystkie dokumenty gdzie images jest w pierwszym rzędzie: true elementu?

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

Oczywiście dotyczy to tylko pola zagnieżdżonego typu boolean, tak jak w tym przypadku.

Powiązane problemy