愚かな集約トリックのカテゴリに分類される 見過ごされがちな小さなテクニックです。
すべてを実行するクエリは、このドキュメントの一意の識別子であるdocument_idを中心にグループ化されます。したがって、考えるべき主なポイントは、ドキュメント全体です。 は実際にはすでに一意の識別子です。したがって、_idキーを単に隠しておくのではなく、ドキュメント全体を使用してください。
{$project: {
_id: { _id: "$_id", name: "$name", forms: "$forms" }, forms: "$forms"}
},
これが行われる場合、_idによってロールアップされたものはすべて、ドキュメントを元の形式で保持します。他のすべての集計ステージの最後に、最後の $ projectを発行します 真の元のドキュメントフォームを復元するには:
{$project: { _id: "$_id._id", name: "$_id.name", forms: "$_id.forms"}}
次に、必要なフィルタリングされた結果が得られます。この手法は、このクエリの場合など、高度なフィルタリングで使用すると、追加の検索を発行する必要がなくなるため、非常に便利です。 すべての結果について。
また、特定の条件のセットに一致する結果のセットのみを探していることがわかっている場合は、 $ matchを使用します。 最初のとしての演算子 集約パイプラインのステージ。これは、ワーキングセットのサイズを縮小するのに役立つだけでなく、のみでもあります。 インデックスを利用できる段階 クエリのパフォーマンスを大幅に向上させることができる場所。
プロセス全体を一緒に:
db.forms.aggregate([
{$match: { "forms.status": "closed" } },
{$project: {
_id: { _id: "$_id", name: "$name", forms: "$forms" }, forms: "$forms"}
},
{$unwind: "$forms"},
{$group: { _id: "$_id", status: {$addToSet: "$forms.status"}}},
{$unwind: "$status"},
{$sort: { _id: 1, status: -1} },
{$group: { _id: "$_id", status: {$first: "$status"} }},
{$match: { status: "closed"}},
{$project: { _id: "$_id._id", name: "$_id.name", forms: "$_id.forms"}}
])