.aggregate()
が必要です
単一の一致以上の配列コンテンツを「フィルタリング」するためのメソッド。また、MongoDBは、指定されたパスが正しい限り、データが配列内にあることを気にしないため、基本的な一致ははるかに単純です。
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 } }}
])
PHPの場合、これは次のように表記されます。
$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
演算子は、外部配列の各要素の検査を許可し、各要素を<に渡します。強い>$cond
三項演算。これにより、 $setIsSubset
が処理されます。
「内部」配列を操作して、代替セット(この場合は[1]
)の値の1つが実際に含まれているかどうかを確認します。 )およびtrue
評価が行われた後、要素が返されるか、そうでなければfalse
。
$setDifference
のポイント
それらのfalse
を削除することです 変更された配列からの値であり、一致した要素のみを返します。そして最後に、 $exists
テストでは、外部配列に実際に少なくとも1つの要素があり、フィルタリングの結果として空ではないことを確認します。
返されるドキュメントは、条件が一致するドキュメントであり、指定された条件にも一致する配列要素のみです。
もちろん、ここでのオペレーターは、サーバーとして少なくともMongoDB 2.6が必要です(これは現在かなり古いリリースであり、少なくとも推奨される更新です)が、それでもより少ないバージョンを使用している場合は、$unwind
および$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' )
)
)
))