2013-04-19 13 views
8

Załóżmy, że mam włożenie zestawu dokumentów, każdy z polem array. Chciałbym znaleźć wszystkie dokumenty w taki sposób, że ich pole array jest podzbiorem tablicy zapytań. Na przykład, jeśli mam następujące dokumenty,Znajdź dokumenty w MongoDB, którego pole tablicy jest podzbiorem tablicy zapytań

collection.insert([ 
    { 
    'name': 'one', 
    'array': ['a', 'b', 'c'] 
    }, 
    { 
    'name': 'two', 
    'array': ['b', 'c', 'd'] 
    }, 
    { 
    'name': 'three', 
    'array': ['b', 'c'] 
    } 
]) 

i kwerendy collection.find({'array': {'$superset': ['a', 'b', 'c']}), spodziewałbym się zobaczyć dokumenty i threeone jak ['a', 'b', 'c'] i ['b', 'c'] są zarówno podzbiory ['a', 'b', 'c']. Innymi słowy, chciałbym wykonać odwrotność zapytania Mongo, które wybiera wszystkie dokumenty w taki sposób, że tablica zapytań jest podzestawem pola array dokumentu. czy to możliwe? a jeśli tak, to w jaki sposób?

+0

Musisz wykonać kilka agregacji IMHO. –

Odpowiedz

9

Istnieje prosty sposób, aby to zrobić za pomocą struktury agregacji lub kwerendy wyszukiwania.

Find zapytanie jest proste, ale trzeba użyć $ Operator elemMatch:

> db.collection.find({array:{$not:{$elemMatch:{$nin:['a','b','c']}}}}, {_id:0,name:1}) 

pamiętać, że oznacza to, że chcemy, aby nie odpowiadać tablicę, która zawiera element, który jest (w tym samym czasie) nie równe "a", "b" lub "c". Dodałem rzut, który zwraca tylko pole nazwy wynikowego dokumentu, który jest opcjonalny.

8

W MongoDB, na polu tablicy:

"$in:[...]" means "intersection" or "any element in", 
"$all:[...]" means "subset" or "contain", 
"$elemMatch:{...}" means "any element match" 
"$not:{$elemMatch:{$nin:[...]}}" means "superset" or "in" 
2

Aby to zrobić w kontekście agregacji, można użyć $setIsSubset:

db.collection.aggregate([ 
    // Project the original doc and a new field that indicates if array 
    // is a subset of ['a', 'b', 'c'] 
    {$project: { 
     doc: '$$ROOT', 
     isSubset: {$setIsSubset: ['$array', ['a', 'b', 'c']]} 
    }}, 
    // Filter on isSubset 
    {$match: {isSubset: true}}, 
    // Project just the original docs 
    {$project: {_id: 0, doc: 1}} 
]) 

Zauważ, że $setIsSubset dodano MongoDB 2.6.

+1

ładny. Z mojej odpowiedzi usunąłem starą nieefektywną agregację, ponieważ jest ona bardziej elegancka i jest już dostępna przez jakiś czas. –

Powiązane problemy