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

【MongoDB】フィールドが存在しないドキュメントにのみタイムスタンプを追加するクエリの書き方

MongoDBでは、update()メソッドと$exists演算子を組み合わせることで、「特定のフィールドが存在しないドキュメントにのみ」日付(タイムスタンプ)を追加できます。この操作には、upsertmultiという2つの重要なオプションを理解しておく必要があります。

upsert と multi オプションとは

upsert

trueに設定すると、クエリ条件に一致するドキュメントが存在しない場合に、新しいドキュメントを作成します。デフォルト値はfalseで、この場合は一致するドキュメントがなくても新規挿入は行われません。

multi

trueに設定すると、クエリ条件に一致する複数のドキュメントを一括で更新します。falseの場合は、最初に見つかった1件のみ更新されます。デフォルト値はfalseです。

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

まず、ドキュメントを含むコレクションを作成します。ここでは、DueDateフィールドを持つドキュメントと持たないドキュメントを混在させて登録します。

> db.demo479.insertOne({"DueDate":new ISODate("2020-01-10"),"Name":"Chris"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e820733b0f3fa88e2279094") }
> db.demo479.insertOne({"Name":"David"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e820748b0f3fa88e2279095") }
> db.demo479.insertOne({"DueDate":new ISODate("2019-12-31"),"Name":"Bob"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e82075fb0f3fa88e2279096") }
> db.demo479.insertOne({"Name":"Carol"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e820767b0f3fa88e2279097") }

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

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

> db.demo479.find();

実行結果は以下の通りです。「David」と「Carol」のドキュメントにはDueDateフィールドが存在しないことがわかります。

{ "_id" : ObjectId("5e820733b0f3fa88e2279094"),
  "DueDate" : ISODate("2020-01-10T00:00:00Z"), "Name" : "Chris" }
{ "_id" : ObjectId("5e820748b0f3fa88e2279095"), "Name" : "David" }
{ "_id" : ObjectId("5e82075fb0f3fa88e2279096"),
  "DueDate" : ISODate("2019-12-31T00:00:00Z"), "Name" : "Bob" }
{ "_id" : ObjectId("5e820767b0f3fa88e2279097"), "Name" : "Carol" }

フィールドが存在しないドキュメントにのみタイムスタンプを追加するクエリ

以下のクエリでは、$exists: falseによってDueDateフィールドが存在しないドキュメントだけを対象にし、$setで現在の日時を追加しています。

> db.demo479.update(
...   {DueDate:{$exists:false}},
...   {$set : {"DueDate":new Date}},
...   {upsert:false, multi:true}
... );
WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 })

WriteResultの出力を見ると、2件のドキュメントがマッチし、2件が更新されたことが確認できます。

更新後の結果確認

再度find()メソッドを実行して、すべてのドキュメントを表示してみましょう。

> db.demo479.find();

実行結果:

{ "_id" : ObjectId("5e820733b0f3fa88e2279094"),
  "DueDate" : ISODate("2020-01-10T00:00:00Z"), "Name" : "Chris" }
{ "_id" : ObjectId("5e820748b0f3fa88e2279095"),
  "Name" : "David", "DueDate" : ISODate("2020-03-30T14:52:29.656Z") }
{ "_id" : ObjectId("5e82075fb0f3fa88e2279096"),
  "DueDate" : ISODate("2019-12-31T00:00:00Z"), "Name" : "Bob" }
{ "_id" : ObjectId("5e820767b0f3fa88e2279097"),
  "Name" : "Carol", "DueDate" : ISODate("2020-03-30T14:52:29.656Z") }

上記の結果から、「David」と「Carol」のドキュメントにのみ新しいDueDateが追加され、すでにDueDateを持っていた「Chris」と「Bob」の値はそのまま維持されていることが確認できます。

ポイントまとめ

  • {フィールド名: {$exists: false}}を検索条件にすることで、フィールドが存在しないドキュメントだけを抽出できる
  • multi: trueを指定することで、条件に一致した全ドキュメントを一括更新できる
  • 既存のフィールド値を上書きせずに欠損データだけを補完したいケースに有効な手法
  1. MongoDBで特定フィールドの値を合計するクエリの書き方(aggregate + $sum)

    MongoDBでは、aggregate()メソッドと$group・$sum演算子を組み合わせることで、コレクション内のドキュメントに含まれる特定フィールドの値を簡単に合計できます。この記事では、実際のコマンド例を使いながら手順をわかりやすく解説します。1. サンプルコレクションの作成まず、ドキュメントを含むコレクションを作成します。ここではdemo677というコレクションに、Valueフィールドを持つ4件のドキュメントを挿入します。> db.demo677.insertOne({Value:10}); { acknowledged : true, insertedId :

  2. MongoDBで配列の要素を1つだけ取得する方法|$slice演算子の使い方

    MongoDBの$sliceで配列の要素を1つだけ取得する配列から特定の件数の要素だけを取り出したい場合、MongoDBでは$slice演算子を使用します。$sliceはプロジェクション演算子の一種で、指定した件数分の配列要素のみを返すことができます。ここでは、実際にコレクションを作成し、$sliceを使って配列の先頭1件だけを取得する手順を順番に見ていきましょう。サンプルデータの作成まず、insertOne()メソッドを使ってドキュメントをコレクションに挿入します。> db.demo579.insertOne( ... { ... _id : 101, ...