$addFieldsパイプラインとMongoDBの$filterオペレーターを使って配列をフィルタリングする方法
$addFieldsパイプラインと$filterオペレーターの組み合わせ
MongoDBでは、集計パイプライン(aggregate())内で$addFieldsステージと$filterオペレーターを組み合わせることで、ドキュメント内の配列要素を条件に応じて絞り込むことができます。この記事では、実際のコード例を使いながら、その具体的な使い方を解説します。
1. コレクションを作成してドキュメントを挿入する
まず、insertOne()メソッドを使ってサンプルコレクションを作成しましょう。
> db.demo118.insertOne(
... {
... "Id" : "101",
... "Name" : "Chris",
... "Subjects" : [
... "MySQL",
... "MongoDB",
... "Java"
... ],
... "Details" : [
... {
... "Name" : "David",
... S:"MongoDB"
... },
... {
... "Name" : "Bob",
... S:"Python"
... }
... ]
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5e2f0c0cd8f64a552dae6364")
}
2. find()メソッドですべてのドキュメントを表示する
find()メソッドを使うと、コレクション内のすべてのドキュメントを確認できます。
> db.demo118.find();
実行すると、次のような出力が得られます。
{ "_id" : ObjectId("5e2f0c0cd8f64a552dae6364"), "Id" : "101", "Name" : "Chris", "Subjects" : [ "MySQL", "MongoDB", "Java" ], "Details" : [ { "Name" : "David", "S" : "MongoDB" }, { "Name" : "Bob", "S" : "Python" } ] }
3. $addFieldsパイプラインと$filterを使ったクエリ
ここからが本題です。$addFieldsパイプラインの中で$filterオペレーターを使用し、「Details」配列の各要素の「S」フィールドが「Subjects」配列に含まれているかどうかを$in演算子で判定して、条件に合致する要素だけを残します。
> db.demo118.aggregate([
... {
... "$addFields": {
... "Details": {
... "$filter": {
... "input": "$Details",
... "as": "out",
... "cond": { "$in": ["$$out.S", "$Subjects"] }
... }
... }
... }
... }
... ]).pretty();
4. 実行結果
上記のクエリを実行すると、次の出力が得られます。
{
"_id" : ObjectId("5e2f0c0cd8f64a552dae6364"),
"Id" : "101",
"Name" : "Chris",
"Subjects" : [
"MySQL",
"MongoDB",
"Java"
],
"Details" : [
{
"Name" : "David",
"S" : "MongoDB"
}
]
}
処理内容のポイント
元の「Details」配列には「David(S: MongoDB)」と「Bob(S: Python)」の2つの要素がありましたが、結果を見ると「David」の要素のみが残っています。これは以下の理由によります。
- $filterのcond条件: 各要素(変数名
outとして参照)の「S」フィールドの値が、「Subjects」配列に含まれるかをチェックしています。 - $in演算子: Davidの「MongoDB」はSubjects配列に存在するため残り、Bobの「Python」は存在しないため除外されました。
- $addFieldsの役割: 既存の「Details」フィールドを、フィルタリング済みの新しい配列で上書きしています。
このように、$addFieldsと$filterを組み合わせれば、ネストされた配列データを柔軟に加工でき、別のコレクションやフィールドとの関連性に基づいた高度なデータ整形も簡単に実現できます。
-
MongoDBで配列要素をグループ化し、同じ価格の製品数をカウントする方法
MongoDBで配列内のアイテムをグループ化するには、$group演算子を$sortと組み合わせて使用します。この記事では、実際にコレクションを作成しながら、同じ価格の製品をカウントする手順を詳しく解説します。サンプルコレクションの作成まず、ドキュメントを含むコレクションを作成しましょう。以下の例では、複数の製品情報(ProductInformation)を配列として持つドキュメントを挿入します。> db.demo566.insertOne( ... { ... ... ProductInformation : [ ... { ... Produ
-
MongoDBでIDを並べ替えてアイテムを逆順に取得する方法
MongoDBでは、$naturalを使用するとドキュメントが自然順(natural order)で返されます。この順序を逆にしたい場合は、$natural:-1を指定します。サンプルコレクションの作成まず、ドキュメントを含むコレクションを作成しましょう。> db.demo710.insertOne({id:101,Name:"Robert"}); { "acknowledged" : true, "insertedId" : ObjectId("5ea83a855d33e20ed1097b7a&quo