PHPと組み合わせたmongoDBでのaggregateの特定の使用



Specific Use Aggregate Mongodb Combined With Php



最近、mongoDBの使い方を学んでいます。この記事では、aggregateの具体的な使用法を紹介します。

グループ化の例を見てみましょう。この場合$groupはパイプ演算子です。取得した結果は次のパイプに出力できますが、内部$sumは式演算子です。



使用$group例えば

Group documents for statistical results db.Ubisoft.aggregate([ // aggregate method receives an array { $group: { _id: '$time', num: {$sum: 1} } } ]) // The _id field here indicates which field you want to group based on (that is, the same set of field values ​​are the same), where $time means to group based on the time field. // The value of the following num field $sum: 1 indicates that the number of the group that satisfies the same time field is multiplied by the value given later (in this case, 1, then the number of the same group).

この例を読んだ後、mongoDBには他のパイプライン演算子と式演算子があります。

パイプオペレーター



共通パイプライン 意味
$ group 統計結果のためにコレクション内のドキュメントをグループ化する
$ match データをフィルタリングし、結果に一致するドキュメントのみを出力します
$ project 入力ドキュメントの構造を変更します(名前の変更、フィールドの追加、削除、決済結果の作成など)。
$ sort 結果と出力を並べ替える
$ limit パイプ出力の結果の数を制限します
$ skip 結果の数をスキップして、残りの結果を返します
$ unwind 配列型のフィールドを分割する

式演算子

一般的な表現 意味
$ sum 合計を計算します、{KaTeX解析エラー:期待される「EOF」、位置7で「}」を取得:合計:1} ̲は合計x1の値を示します(つまり、合計...合計:「$ specifyfield」}は、指定されたフィールドの値の合計を直接取得することもできます
$ avg 平均値
$分
$ max 最大
$ push 結果ドキュメントの配列に値を挿入します
$ first ドキュメントの並べ替えに従って最初のドキュメントデータを取得します
$ last 同様に、最後のデータを取得します

これらの演算子を学習した後、引き続き$group来て試してみてください。
これで、内部ドキュメントを含むUbisoftというコレクションができました。

/* 1 */ { '_id' : ObjectId('5b0cf67270e4fa02d31de42e'), 'name' : 'rainbowSix Siege', 'time' : 400.0 } /* 2 */ { '_id' : ObjectId('5b0cf69270e4fa02d31de42f'), 'name' : 'Assassin's creed', 'time' : 20.0 } /* 3 */ { '_id' : ObjectId('5b0cf6ad70e4fa02d31de430'), 'name' : 'ghost Recon', 'time' : 0.0 } /* 4 */ { '_id' : ObjectId('5b0d14c870e4fa02d31de436'), 'name' : 'farCry', 'time' : 0.0 }

ここで他の式演算子を試してみましょう。



db.Ubisoft.aggregate([ { $group: { _id: '$time', gameName: {$push: '$name'} } } ])

結果は次のとおりです。

/* 1 */ { '_id' : 20.0, 'gameName' : [ 'Assassin's creed' ] } /* 2 */ { '_id' : 0.0, 'gameName' : [ 'ghost Recon', 'farCry' ] } /* 3 */ { '_id' : 400.0, 'gameName' : [ 'rainbowSix Siege' ] }

同じ時間フィールドを持つドキュメントがグループに分割され、$ push式を使用して、作成したドキュメントの名前フィールドの値も、作成したgameNameの値として配列に配置されていることがわかります。 mongoDBステートメント。

さらに、$group定式化できます_id:nullつまり、すべてのドキュメントを1つにグループ化して、平均値の計算に使用できます。

$選択したドキュメントのすべてのコンテンツを表すのに加えて、$$ROOTフィールドを指定して、選択したドキュメントのフィールドを表すことができます(例:chosenDocument: {$push: '$$ROOT'}

上記の例では、基本的に式演算子の使用法を紹介しています。

次に見てください$match

$match

db.Ubisoft.aggregate([ { $match: { Time: {$gte: 20} //Select document with time field >=20 } } ])

これにより、時間> = 20のすべてのドキュメントが取得され、別のパイプを接続して別の操作を実行できます。たとえば、別のパイプを取得できます。$groupグループ化するには、すべての時間のドキュメント数を表示します> = 20は除外されました。

db.Ubisoft.aggregate([ { $match: { time: {$gte: 20} } }, { $group: { _id: null, // _id: null means select all totalNum: {$sum: 1} } } ])

出力は次のとおりです。

/* 1 */ { '_id' : null, 'totalNum' : 2.0 }

時間> = 20のドキュメントの数が2であることがわかります。

$project投影

入力ドキュメントの構造を変更します(名前の変更、フィールドの追加、削除、決済結果の作成など)。

$projectそして直接使用するfind()同じ書き方:

db.Ubisoft.aggregate([ { $project: { _id: 0, //Do not display _id field } } ])

私たちと直接書くdb.Ubisoft.find({},{'_id': 0})書かれた
出力は次のとおりです。

/* 1 */ { 'name' : 'rainbowSix Siege', 'time' : 400.0 } /* 2 */ { 'name' : 'Assassin's creed', 'time' : 20.0 } /* 3 */ { 'name' : 'ghost Recon', 'time' : 0.0 } /* 4 */ { 'name' : 'farCry', 'time' : 0.0 }

見えない_idフィールドがなくなった。

したがって、time> = 20のすべてのドキュメントの名前フィールドを取得する場合は、パイプラインを一緒に使用できます。

db.Ubisoft.aggregate([ { $match: { time: {$gte: 20} } }, { $project: { _id: 0, // _id is not displayed Name: 1 // name is to be displayed } }, { $group: { _id: null, name: {$push: '$name'} } } ])

出力は次のとおりです。

/* 1 */ { '_id' : null, 'name' : [ 'rainbowSix Siege', 'Assassin's creed' ] }

$sort

$sort find()での並べ替えについても同じことが言えます。

ここで、すべてのドキュメントを時間の降順で並べ替えます。

with db.Ubisoft.find().sort({time: -1})記述は同じです:

db.Ubisoft.aggregate([ { $sort: { time: -1 } } ])

同様に、$sort他のパイプラインでも使用できます

$limit $skip

with limit()およびskip()同じことが当てはまります。

db.Ubisoft.find().skip(1).limit(2)

集計を使用して次のように記述します。

db.Ubisoft.aggregate([ { $skip: 1 }, { $limit: 2 } ])

制限とスキップの組み合わせにより、ページ付けを実現できます。

書き込みは最初の書き込み制限をスキップすることに注意してください

$unwind

$unwindパイプは、ドキュメント内の配列タイプのフィールドで分割できます。各フィールドには、配列内の値が含まれています。

  • 基本的な使い方
    次のドキュメントをUbisoftコレクションに追加します。
/* 5 */ { '_id' : ObjectId('5b0e242ed85f6f9cc56da7cc'), 'name' : 'gameList', 'list' : [ 'dota2', 'csgo', 'ow' ] }

このドキュメントのリストフィールドに対してこれを行います。$unwind

db.Ubisoft.aggregate([ { $unwind: '$list' // specify the list field } ])

出力は次のとおりです。

/* 1 */ { '_id' : ObjectId('5b0e242ed85f6f9cc56da7cc'), 'name' : 'gameList', 'list' : 'dota2' } /* 2 */ { '_id' : ObjectId('5b0e242ed85f6f9cc56da7cc'), 'name' : 'gameList', 'list' : 'csgo' } /* 3 */ { '_id' : ObjectId('5b0e242ed85f6f9cc56da7cc'), 'name' : 'gameList', 'list' : 'ow' }

unwindは、ドキュメント内の配列フィールドを分割することであることがわかります。他のドキュメントがある場合、リストフィールドも配列であり、一緒に分割されます。

  • 特別な場合(null配列、null、非配列、指定されたフィールドなし)でアンワインド

特別な場合は、次の内容で新しいコレクションを作成します。

/* 1 */ { '_id' : ObjectId('5b0e27fdd85f6f9cc56da7ce'), 'list' : null } /* 2 */ { '_id' : ObjectId('5b0e2827d85f6f9cc56da7cf'), 'list' : [] } /* 3 */ { '_id' : ObjectId('5b0e2834d85f6f9cc56da7d0'), 'list' : 'notArray' } /* 4 */ { '_id' : ObjectId('5b0e2844d85f6f9cc56da7d1') }

さあ$unwind

db.unwind.aggregate([ { $unwind: '$list' } ])

出力は次のとおりです。

/* 1 */ { '_id' : ObjectId('5b0e2834d85f6f9cc56da7d0'), 'list' : 'notArray' }

見ることができます[]nullそして、指定されたフィールドのないデータは失われます、
データを失わないために、次のように書くことができます。

db.unwind.aggregate([ { $unwind: { Path: '$list', // path is the specified field preserveNullAndEmptyArrays: true //This property is true and is reserved } } ])

この出力は、nullおよび空の配列を保持します。注意する価値があります。preserveNullAndEmptyArraysこのプロパティはtrueの場合に予約されています。

以下のPHPコードを組み合わせる

//$server according to your own server $mongo = new MongoClient($server, array('connect'=>true))// Connect now $db = $mongo->colName//Select database $collection = $db->file_log//Select document collection $filter['status'] = array('$in' => array(0, 2, 5)) $filter['a_id'] = array('$eq' => $a_id) $group = array('_id' => array( 'md5' => '$md5', 'path' => '$path', 'a_id'=>'$a_id' ), 'time' => array('$last' => '$found_time'), 'l_id' => array('$last' => '$_id'), 'v_name' => array('$last' => '$v_name'), 'c_iso_key' => array('$last' => '$c_iso_key'), 'status' => array('$last' => '$status'), 'h_msg' => array('$last' => '$h_msg'), 'r_level' => array('$last' => '$r_level'), ) $sort = array('time' => 1) // sort by time $limit = 5 / / Get the md5, path, a_id group to get the field as the found_time, _id, v_name last data, time flashback, take out 5 $res = $collection->aggregate(array('$match' => $filter),array('$group' => $group),array('$sort' => $sort),array('$limit'=>(int)$limit))