Potřebujete .aggregate()
metoda za účelem „filtrování“ jakéhokoli obsahu pole pro více než singulární shodu a také základní shoda je mnohem jednodušší, protože MongoDB se nestará o to, že data jsou v polích, pokud je zadaná cesta správná:
db.collection.aggregate([
{ "$match": { "data.userid": 1 } },
{ "$project": {
"data": {
"$setDifference": [
{ "$map": {
"input": "$data",
"as": "el",
"in": {
"$cond": [
{ "$setIsSubset": [ [1], "$$el.userid" ] },
"$$el",
false
]
}
}},
[false]
]
}
}},
{ "$match": { "data.0": { "$exists": true } }}
])
S PHP to zaznamená takto:
$collection->aggregate(array(
array( '$match' => array( "data.userid" => 1 )),
array(
'$project' => array(
'data' => array(
'$setDifference' => array(
array(
'$map' => array(
'input' => '$data',
'as' => 'el',
'in' => array(
'$cond' => array(
array( '$setIsSubset' => array(array(1),'$$el.userid') ),
'$$el',
FALSE
)
)
)
),
array(FALSE)
)
)
)
),
array( '$match' => array( 'data.0' => array( '$exists' => TRUE ) ) )
))
$map
operátor umožňuje kontrolu každého prvku vnějšího pole a předal každý prvek do $cond
ternární operace. Tím se zpracuje $setIsSubset
operaci na "vnitřním" poli, abyste zjistili, zda ve skutečnosti obsahuje jednu z hodnot v alternativní sadě (v tomto případě [1]
) a kde true
provede se vyhodnocení, pak je prvek vrácen nebo jinak false
.
Pointa $setDifference
je odstranit tyto false
hodnoty z upraveného pole a vrátí pouze odpovídající prvky. A nakonec $exists
test vypadá, že vnější pole má ve skutečnosti alespoň jeden prvek a není prázdné v důsledku filtrování.
Vrácené dokumenty jsou dokumenty s odpovídající podmínkou a pouze prvky pole, které také odpovídají zadané podmínce.
Operátoři zde samozřejmě vyžadují, abyste měli jako server alespoň MongoDB 2.6 (což je nyní poměrně stará verze a alespoň doporučená aktualizace), ale pokud stále máte nižší verzi, potřebujete tradiční přístup s $unwind
a $group
:
$collection->aggregate(array(
array( '$match' => array( "data.userid" => 1 )),
array( '$unwind' => '$data' ),
array( '$match' => array( 'data.userid' => 1 )),
array(
'$group' => array(
'_id' => '$_id',
'data' => array( '$push' => '$data' )
)
)
))