$zip(集計)
定義
$zip
入力配列の配列を変換して、出力配列の最初の要素は、最初の入力配列の最初の要素、2 番目の入力配列の最初の要素などを含む配列になります。
たとえば、
$zip
は[ [ 1, 2, 3 ], [ "a", "b", "c" ] ]
を[ [ 1, "a" ], [ 2, "b" ], [ 3, "c" ] ]
に変換します。$zip
の構文は次のとおりです。{ $zip: { inputs: [ <array expression1>, ... ], useLongestLength: <boolean>, defaults: <array expression> } } オペランド説明inputs
useLongestLength
最も長い配列の長さによって出力配列内の配列の数が決定されるかどうかを指定するブール値。
デフォルト値は
false
です。配列の長さは短い方で、出力配列内の配列数が決まります。defaults
動作
入力配列は同じ長さである必要はありません。 デフォルトでは、出力配列の長さは短い入力配列の長さですが、 useLongestLength
オプションは、最も長い入力配列と同じ長さの配列を出力するように$zip
に指示します。
例 | 結果 | |||||||
---|---|---|---|---|---|---|---|---|
|
| |||||||
|
| |||||||
|
| |||||||
|
これにより |
例
マトリクストランス位置
matrices
というコレクションには次のドキュメントが含まれています。
db.matrices.insertMany([ { matrix: [[1, 2], [2, 3], [3, 4]] }, { matrix: [[8, 7], [7, 6], [5, 4]] }, ])
このコレクション内の各 3x2 マトリックスのトランスポートを計算するには、次の集計操作を使用できます。
db.matrices.aggregate([{ $project: { _id: false, transposed: { $zip: { inputs: [ { $arrayElemAt: [ "$matrix", 0 ] }, { $arrayElemAt: [ "$matrix", 1 ] }, { $arrayElemAt: [ "$matrix", 2 ] }, ] } } } }])
これにより、次の 2x3 のマトリックスが返されます。
{ "transposed" : [ [ 1, 2, 3 ], [ 2, 3, 4 ] ] } { "transposed" : [ [ 8, 7, 5 ], [ 7, 6, 4 ] ] }
インデックスのフィルタリングと保持
$zip
を$filter
と併用すると、配列内の要素のサブセットを取得でき、保持された各要素と一緒に元のインデックスを保存できます。
pages
というコレクションには次のドキュメントが含まれています。
db.pages.insertOne( { "category": "unix", "pages": [ { "title": "awk for beginners", reviews: 5 }, { "title": "sed for newbies", reviews: 0 }, { "title": "grep made simple", reviews: 2 }, ] } )
次の集計パイプラインでは、まずpages
配列の要素をインデックスとともに zip 化し、次に少なくとも 1 件のレビューがあるページのみをフィルタリングで除外します。
db.pages.aggregate([{ $project: { _id: false, pages: { $filter: { input: { $zip: { inputs: [ "$pages", { $range: [0, { $size: "$pages" }] } ] } }, as: "pageWithIndex", cond: { $let: { vars: { page: { $arrayElemAt: [ "$$pageWithIndex", 0 ] } }, in: { $gte: [ "$$page.reviews", 1 ] } } } } } } }])
これにより、次のドキュメントが返されます。
{ "pages" : [ [ { "title" : "awk for beginners", "reviews" : 5 }, 0 ], [ { "title" : "grep made simple", "reviews" : 2 }, 2 ] ] }