MongoDB
 Computer >> コンピューター >  >> プログラミング >> MongoDB

MongoDBで$first演算子に$$ROOTを組み合わせてルートドキュメントへの参照を取得する方法

$first演算子と$$ROOTシステム変数の概要

アキュムレータ(累積演算子)とは、ドキュメントが集計パイプライン(aggregation pipeline)を通過していく過程で内部状態を保持し続ける演算子のことです。代表的なものには $sum、$max、$min、$first などがあります。

一方、$$ROOT はシステム変数の一つで、現在処理中の集計ステージにおけるルートドキュメント、つまり最上位階層のドキュメントそのものへの参照を表します。この2つを組み合わせることで、グループ化した際の最初のドキュメント全体を簡単に取得できます。

サンプルコレクションの作成

まず、ドキュメントを含むコレクションを作成しましょう。

> db.demo582.insertOne({FirstName:"Chris",Age:21,createDate:new ISODate("2020-01-10")});{
   "acknowledged" : true, "insertedId" : ObjectId("5e91ce41fd2d90c177b5bcbd")
}
> db.demo582.insertOne({FirstName:"Chris",Age:21,createDate:new ISODate("2020-04-21")});{
   "acknowledged" : true, "insertedId" : ObjectId("5e91ce4ffd2d90c177b5bcbe")
}
> db.demo582.insertOne({FirstName:"Chris",Age:22,createDate:new ISODate("2020-02-11")});{
   "acknowledged" : true, "insertedId" : ObjectId("5e91ce59fd2d90c177b5bcbf")
}
> db.demo582.insertOne({FirstName:"Chris",Age:22,createDate:new ISODate("2020-01-12")});{
   "acknowledged" : true, "insertedId" : ObjectId("5e91ce6efd2d90c177b5bcc0")
}

登録済みドキュメントの確認

find() メソッドを使って、コレクション内のすべてのドキュメントを表示します。

> db.demo582.find();

実行すると、次のような出力が得られます。

{ "_id" : ObjectId("5e91ce41fd2d90c177b5bcbd"), "FirstName" : "Chris", "Age" : 21, "createDate" : ISODate("2020-01-10T00:00:00Z") }
{ "_id" : ObjectId("5e91ce4ffd2d90c177b5bcbe"), "FirstName" : "Chris", "Age" : 21, "createDate" : ISODate("2020-04-21T00:00:00Z") }
{ "_id" : ObjectId("5e91ce59fd2d90c177b5bcbf"), "FirstName" : "Chris", "Age" : 22, "createDate" : ISODate("2020-02-11T00:00:00Z") }
{ "_id" : ObjectId("5e91ce6efd2d90c177b5bcc0"), "FirstName" : "Chris", "Age" : 22, "createDate" : ISODate("2020-01-12T00:00:00Z") }

グループアキュムレータ演算子を適用するクエリ

続いて、$group ステージ内で $first 演算子に $$ROOT を指定することで、各グループの最初のルートドキュメントへの参照を取得します。あわせて $max で最新の日付を、$sum で件数も求めています。

> db.demo582.aggregate([
...    {
...        "$group": {
...            "_id": "$FirstName",
...            "MaximumDate": {
...                "$max": "$createDate"
...            },
...            "count": {
...                "$sum": 1
...            },
...            "details": {
...                "$first": "$$ROOT"
...            }
...        }
...    },
...    {
...        "$project": {
...            "MaximumDate": 1,
...            "count": 1,
...            "details": {
...                "_id": "$_id",
...                "FirstName": "$details.FirstName",
...                "Age" : "$details.Age"
...            }
...        }
...    }
... ])

実行結果

上記のクエリを実行すると、次のような出力が得られます。

{ "_id" : "Chris", "MaximumDate" : ISODate("2020-04-21T00:00:00Z"), "count" : 4, "details" :
   { "_id" : "Chris", "FirstName" : "Chris", "Age" : 21 }
}

解説

この結果からわかるように、$group ステージでは FirstName をキーとしてドキュメントがグループ化され、$max によって createDate の最大値(2020-04-21)が取得されています。また、$first: "$$ROOT" の指定により、グループ内で最初に処理されたドキュメント全体への参照が details フィールドに格納され、その後の $project ステージで必要なフィールドだけが整形されて出力されます。このテクニックは、グループごとの代表ドキュメントを取得したい場合に非常に便利です。

  1. JavaScriptで数値の立方根を求める方法!Math.cbrt()メソッドの使い方を解説

    JavaScriptのMathオブジェクトと立方根JavaScriptでは、Mathオブジェクトを使用することで、さまざまな数学的な操作を実行できます。その中でもMath.cbrt()は、数値の立方根(三乗根)を求めるために特化したメソッドです。引数として数値を1つ受け取り、その立方根の値を戻り値として返します。平方根を求めるMath.sqrt()とは異なり、負の数に対しても有効な結果を返せる点が大きな特徴です。数学的に、負の数の立方根も実数として定義されるためです。構文Math.cbrt(64);引数に数値を渡すと、その立方根の値が戻り値として返されます。例1:正の値の立方根を求める次の例で

  2. JavaScriptで<text>要素の値を変数に抽出する方法

    JavaScriptで要素の値を変数に抽出するにはSVGの<text>要素のテキスト値を変数に抽出したい場合は、textContentプロパティを使用します。基本的な書き方は以下の通りです。document.getElementById(yourTextIdValue).textContentgetElementById()メソッドで対象の要素をIDから取得し、そのtextContentプロパティを参照することで、要素内のテキストを文字列として変数に格納できます。textContentとinnerHTMLの違いなお、SVG要素の場合はinnerHTMLよりもtextContentを