MongoDBで配列内をネイティブクエリしてカウントを取得する方法
MongoDBでは、配列の中身を調べて特定のフィールドが存在するかどうかを確認し、その件数(カウント)を取得したいケースがよくあります。そんなときに便利なのが $exists 演算子です。この記事では、$exists を使って配列内のフィールド存在チェックを行い、該当ドキュメント数を取得する手順を解説します。
サンプルコレクションの作成
まずは、ドキュメントを含むコレクションを作成しましょう。以下のように insertOne() メソッドを使って3件のドキュメントを挿入します。
> db.demo296.insertOne(
... {
... "id":101,
... "Name":"Chris",
... "details":[
... {
... SubjectId:[101,103],
... "SubjectName":["MySQL","MongoDB"]
... },
... {
... SubjectId:[102,104],
... "SubjectName":["Java","C"]
... }
... ]
... }
...);
{
"acknowledged" : true,
"insertedId" : ObjectId("5e4d51715d93261e4bc9ea3b")
}続いて2件目のドキュメントです。こちらは details 配列内に SubjectId のみを持つ構造になっています。
> db.demo296.insertOne(
...{
... "id":102,
... "Name":"David",
... "details":[
... {
... SubjectId:[110,113]
...
... },
... {
... SubjectId:[112,114]
...
... }
... ]
...}
...);
{
"acknowledged" : true,
"insertedId" : ObjectId("5e4d519b5d93261e4bc9ea3c")
}さらに3件目として、SubjectName のみを持つドキュメントを挿入します。
> db.demo296.insertOne(
... {
... "id":103,
... "Name":"Bob",
... "details":[
... {
... "SubjectName":["C++","Python"]
... },
... {
... "SubjectName":["Spring","Hibernate"]
... }
... ]
... }
...);
{
"acknowledged" : true,
"insertedId" : ObjectId("5e4d52315d93261e4bc9ea3d")
}find()メソッドで全ドキュメントを表示
挿入したデータを確認するために、find() メソッドでコレクション内のすべてのドキュメントを表示してみましょう。
> db.demo296.find();
実行すると、次のような出力が得られます。
{
"_id" : ObjectId("5e4d51715d93261e4bc9ea3b"), "id" : 101, "Name" : "Chris", "details" : [
{ "SubjectId" : [ 101, 103 ], "SubjectName" : [ "MySQL", "MongoDB" ] },
{ "SubjectId" : [ 102, 104 ], "SubjectName" : [ "Java", "C" ] }
]
}
{
"_id" : ObjectId("5e4d519b5d93261e4bc9ea3c"), "id" : 102, "Name" : "David", "details" : [
{ "SubjectId" : [ 110, 113 ] }, { "SubjectId" : [ 112, 114 ] }
]
}
{
"_id" : ObjectId("5e4d52315d93261e4bc9ea3d"), "id" : 103, "Name" : "Bob", "details" : [
{ "SubjectName" : [ "C++", "Python" ] }, { "SubjectName" : [ "Spring", "Hibernate" ] }
]
}ここで注目すべきポイントは、各ドキュメントの details 配列内に含まれるフィールドが異なることです。1件目は SubjectId と SubjectName の両方を持ち、2件目は SubjectId のみ、3件目は SubjectName のみを持っています。
$exists演算子で配列内のフィールド存在を確認しカウントを取得
それでは本題です。details.SubjectName フィールドが存在するドキュメントの件数を取得するには、count() メソッドと $exists 演算子を組み合わせて次のようにクエリを実行します。
> db.demo296.count( { 'details.SubjectName': {$exists: true }} );実行結果は以下の通りです。
2
結果として「2」が返されました。これは、details 配列内に SubjectName フィールドを持つドキュメントが2件(id: 101 の Chris と id: 103 の Bob)存在するためです。id: 102 の David のドキュメントは SubjectId のみしか持たないため、カウント対象から除外されています。
まとめ
このように、$exists: true を使うことで、配列内のネストされたフィールドの存在有無を簡単に判定できます。ドット記法(details.SubjectName)でパスを指定することで、配列内のオブジェクトも柔軟に検索できるのがMongoDBの強みです。なお、新しいバージョンのMongoDBでは count() の代わりに countDocuments() の使用が推奨されているため、実運用ではそちらを採用するとよいでしょう。
-
MongoDBで配列要素をグループ化し、同じ価格の製品数をカウントする方法
MongoDBで配列内のアイテムをグループ化するには、$group演算子を$sortと組み合わせて使用します。この記事では、実際にコレクションを作成しながら、同じ価格の製品をカウントする手順を詳しく解説します。サンプルコレクションの作成まず、ドキュメントを含むコレクションを作成しましょう。以下の例では、複数の製品情報(ProductInformation)を配列として持つドキュメントを挿入します。> db.demo566.insertOne( ... { ... ... ProductInformation : [ ... { ... Produ
-
MongoDBで配列の要素数をカウントし、新しいフィールドに表示する方法
ドキュメント内の配列要素の数をカウントするには、MongoDBの $size 演算子を使用します。$size は集計パイプライン(aggregate)の中で利用でき、指定した配列フィールドに含まれる要素の総数を数値として返します。ここでは、実際にコレクションを作成しながら、配列要素数をカウントして新しいフィールドに表示する手順を解説します。1. コレクションの作成まず、ドキュメントを挿入してコレクションを作成します。各ドキュメントには科目名を格納する配列フィールド「ListOfSubject」を持たせます。> db.demo703.insertOne({ListOfSubject:[My