MongoDB findAndModify()の例

MongoDBのfindAndModify()メソッドは、入力された選択基準に基づいて単一のドキュメントを変更して返します。返されるドキュメントは、デフォルトでは更新されたコンテンツを表示しません。データベースに基準に一致するレコードが存在しない場合、upsertがtrueに設定されている場合は、新しいレコードが挿入されます。

MongoDBのfindAndModify()

mongodb findAndModifyメソッドの構文は次のとおりです。

db.collection.findAndModify({
    query: <document>,
    sort: <document>,
    new: <boolean>,
    fields: <document>,
    upsert: <boolean>
})

パラメータの説明は次のとおりです。query:変更が必要なレコードを指定する選択基準を定義します。sort:選択基準が複数のドキュメントを取得する場合、どのドキュメントを変更するかを決定します。new:変更されたドキュメントが表示されることを示します。fields:返されるフィールドのセットを指定します。upsert:選択基準がドキュメントを取得できない場合は新しいドキュメントを作成します。

MongoDBのfindAndModifyの重要なポイント

findAndModify MongoDB呼び出しを使用する際に心に留めておくべきことのいくつかは次のとおりです:

  • 入力された選択基準がドキュメントを取得しない場合、およびupsertがtrueに設定されている場合、指定された値が挿入され、新しいドキュメントが作成されます。
  • 入力された選択基準が更新または削除操作を実行する際にドキュメントを取得しない場合、返される出力はnullです。
  • 新しいオプションがfalseに設定されており、ソート操作が指定されていない場合、返される出力はnullです。
  • 新しいオプションがfalseに設定されており、ソート操作が指定されている場合、出力は空です。

MongoDBのfindAndModifyの例

それでは、findAndModify APIの使用例を示すいくつかの例を見てみましょう。まず、テストデータを作成して開始します。mongoコンソールを介して、名前、色、車の番号(cno)、速度、製造国(mfdcountry)のフィールドを持つ新しい車のドキュメントを作成します。

db.car.insert(
[
{ _id: 1, name: "Alto", color: "Red",cno: "H410",speed:40,mfdcountry: "India"},
{ _id: 2, name: "Polo", color: "White",cno: "H411",speed:45,mfdcountry: "Japan" },
{ _id: 3, name: "Audi", color: "Black",cno: "H412",speed:50,mfdcountry: "Germany" }
]
)

次に、実際に挿入されたデータを確認しましょう:mongodb find

db.car.find()
{ "_id" : 1, "name" : "Alto", "color" : "Red", "cno" : "H410", "speed" : 40, "mfdcountry" : "India" }
{ "_id" : 2, "name" : "Polo", "color" : "White", "cno" : "H411", "speed" : 45, "mfdcountry" : "Japan" }
{ "_id" : 3, "name" : "Audi", "color" : "Black", "cno" : "H412", "speed" : 50, "mfdcountry" : "Germany" }

findおよびmodifyの実際の使用例に移り、異なる可能性を示します。ケース1:ドキュメントがデータベースに存在する場合

db.car.findAndModify({
query: { name: "Alto" },
sort: { cno: 1 },
update: { $inc: { speed: 10 } },
})
  1. クエリは、車コレクション内で名前フィールドの値がAltoであるドキュメントを見つけます。
  2. クエリの結果を昇順で並べ替えます。複数のドキュメントがクエリ条件を満たす場合、この並び順に従って最初のドキュメントが更新対象として選択されます。
  3. 更新は、speedフィールドの値を10増加させます。
  4. この更新に選択された元のドキュメントが返されます:

出力:

{
"_id" : 1,
"name" : "Alto",
"color" : "Red",
"cno" : "H410",
"speed" : 40,
"mfdcountry" : "India"
}

ケース2:新しいオプションをtrueに設定(更新されたデータセットを返す)

db.car.findAndModify({
query: { name: "HondaCity", color: "Silver", cno:"H415" ,speed: 25 },
sort: { cno: 1 },
update: { $inc: { speed: 20 } },
upsert: true,
new: true
})

出力:

{
"_id" : ObjectId("546c9f347256eabc40c9da1c"),
"cno" : "H415",
"color" : "Silver",
"name" : "HondaCity",
"speed" : 45
}

speedは45と表示されていますが、これは更新された値です。もし新しく設定されていない場合、speedフィールドは20と表示されますが、データベースでは更新されます。ケース3:upsertがtrueに設定されています

db.car.findAndModify({
query: { name: "WagonR" },
sort: { cno: 1 },
update: { $inc: { speed: 5 } },
upsert: <strong>true</strong>
})

出力:

db.car.find();
{ "_id" : 1, "name" : "Alto", "color" : "Red", "cno" : "H410", "speed" : 50, "mfdcountry" : "India" }
{ "_id" : 2, "name" : "Polo", "color" : "White", "cno" : "H411", "speed" : 45, "mfdcountry" : "Japan" }
{ "_id" : 3, "name" : "Audi", "color" : "Black", "cno" : "H412", "speed" : 50, "mfdcountry" : "Germany" }
{ "_id" : ObjectId("546c7c7d6be0faf69ee36546"), "name" : "WagonR", "speed" : 5 }

WagonRという車名はdbに存在しないため、新しいドキュメントがデータベースに作成されます。sortオプションが指定されている場合、メソッドは空のドキュメント { } を返します。sortオプションが含まれていない場合、メソッドはnullを返します。これに加えて、ソートと削除の操作にも使用できます。removeフィールドがtrueに設定されている場合、指定された条件の車名がデータベースから削除されます。

db.car.findAndModify(
{
query: { name: "Alto" },
sort: { cno: 1 },
remove: true
}
)

出力:

{
"_id" : 1,
"name" : "Alto",
"color" : "Red",
"cno" : "H410",
"speed" : 50,
"mfdcountry" : "India"
}

removeフィールドがtrueに設定されているため、名前が「Alto」のドキュメントがデータベースから削除されます。

MongoDBのfindAndModify Javaの例

上記の操作はすべて、mongoシェルを使用して手動で行われます。同じことは以下のようにJavaでプログラムを使って自動化することもできます。mongoドライバーのjarファイルをダウンロードしてクラスパスに追加してください。まず、Mongoクライアントを使用してmongodbサーバーへの接続を確立する必要があります。接続のためにはデータベースの名前がパラメータとして指定される必要があります。データベースが存在しない場合、新しいデータベースが作成されます。その後、データベースにいくつかのレコードを追加し、findAndModify操作を行い、レコードが実際に更新されたかどうかを確認します。以下のプログラムは、mongo javaドライバーのバージョン2.xで動作します。

package com.journaldev.mongodb;

import java.net.UnknownHostException;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.MongoClient;

public class MongoDBFindAndModify {

	public static void main(String[] args) throws UnknownHostException {
		// サーバーが稼働していると仮定して新しい接続を取得します。
		MongoClient mongoClient = new MongoClient("localhost");
		// データベースとしてtestを使用します。ここにあなたのデータベースを使用してください。
		DB db = mongoClient.getDB("test");

		DBCollection coll = db.getCollection("car");
		
		// いくつかのテストデータを挿入します。
		BasicDBObject obj = new BasicDBObject();
		obj.append("name", "Volkswagen");
		obj.append("color", "JetBlue");
		obj.append("cno", "H672");
		obj.append("speed", 62);
		obj.append("mfdcountry", "Italy");
		coll.insert(obj);
		
		// findAndModify操作。speed<45の車の色を青に更新します。
		//<45
		DBObject query = new BasicDBObject("speed",
				new BasicDBObject("$lt", 45));
		DBObject update = new BasicDBObject();
		update.put("$set", new BasicDBObject("color", "Blue"));
		DBCursor cursor = coll.find();
		try {
			while (cursor.hasNext()) {
				System.out.println(cursor.next());
			}
		} finally {
			cursor.close();
		}
		coll.findAndModify(query, update);
	}
}

出力:

//挿入前のテストデータ
{ "_id" : 2.0 , "name" : "Polo" , "color" : "White" , "cno" : "H411" , "speed" : 45.0 , "mfdcountry" : "Japan"}
{ "_id" : 3.0 , "name" : "Audi" , "color" : "Black" , "cno" : "H412" , "speed" : 50.0 , "mfdcountry" : "Germany"}


//挿入後のテストデータ
{ "_id" : 2.0 , "name" : "Polo" , "color" : "White" , "cno" : "H411" , "speed" : 45.0 , "mfdcountry" : "Japan"}
{ "_id" : 3.0 , "name" : "Audi" , "color" : "Black" , "cno" : "H412" , "speed" : 50.0 , "mfdcountry" : "Germany"}
{ "_id" : { "$oid" : "546cc76093f404729e2e946e"} , "name" : "Volkswagen" , "color" : "JetBlue" , "cno" : "H672" , "speed" : 62 , "mfdcountry" : "Italy"}


/*Test Data Before findandModify
{ "_id" : 2.0 , "name" : "Polo" , "color" : "White" , "cno" : "H411" , "speed" : 45.0 , "mfdcountry" : "Japan"}
{ "_id" : 3.0 , "name" : "Audi" , "color" : "Black" , "cno" : "H412" , "speed" : 50.0 , "mfdcountry" : "Germany"}
{ "_id" : { "$oid" : "546cc76093f404729e2e946e"} , "name" : "Volkswagen" , "color" : "JetBlue" , "cno" : "H672" , "speed" : 62 , "mfdcountry" : "Italy"}
{ "_id" : { "$oid" : "546c7c7d6be0faf69ee36546"} , "name" : "WagonR" , "speed" : 5.0}


/*Test Data After findAndModify
{ "_id" : 2.0 , "name" : "Polo" , "color" : "White" , "cno" : "H411" , "speed" : 45.0 , "mfdcountry" : "Japan"}
{ "_id" : 3.0 , "name" : "Audi" , "color" : "Black" , "cno" : "H412" , "speed" : 50.0 , "mfdcountry" : "Germany"}
{ "_id" : { "$oid" : "546cc76093f404729e2e946e"} , "name" : "Volkswagen" , "color" : "JetBlue" , "cno" : "H672" , "speed" : 62 , "mfdcountry" : "Italy"}
{ "_id" : { "$oid" : "546c7c7d6be0faf69ee36546"} , "name" : "WagonR" , "speed" : 5.0 , "color" : "Blue"}

もしMongoDBのjavaドライバーのバージョン3.xを使用している場合、以下のプログラムを使用してください。

package com.journaldev.mongodb.main;

import java.net.UnknownHostException;

import org.bson.Document;
import org.bson.conversions.Bson;

import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
 
public class MongoDBFindAndModify {
 
    public static void main(String[] args) throws UnknownHostException {
        // サーバーが稼働していると仮定して新しい接続を取得します。
        MongoClient mongoClient = new MongoClient("localhost");
        
        // データベースとしてtestを使用します。ここにあなたのデータベースを使用してください。
        MongoDatabase db = mongoClient.getDatabase("test");
 
        MongoCollection coll = db.getCollection("car");
         
        // いくつかのテストデータを挿入します。
        Document obj = new Document();
        obj.append("name", "Volkswagen");
        obj.append("color", "JetBlue");
        obj.append("cno", "H672");
        obj.append("speed", 62);
        obj.append("mfdcountry", "Italy");
        coll.insertOne(obj);
         
        // findAndModify操作。speed<45の車の色を青に更新します。
        Bson query = new Document("speed",
                new Document("$gt", 45));
        Bson update = new Document("$set", 
        			new Document("color", "Blue"));
        
        System.out.println("before update");
        findAndPrint(coll);
        
        coll.findOneAndUpdate(query, update);
        
        System.out.println("after update of color field");
        findAndPrint(coll);
        
        mongoClient.close();

    }

	private static void findAndPrint(MongoCollection coll) {
		FindIterable cursor = coll.find();
        
		for (Document d : cursor)
			System.out.println(d);
	}
}

以下の画像は、上記プログラムの出力を示しています。色のフィールドが変更されたことに注意してください。これでMongoDBのfindAndModifyの例はすべてです。今後の投稿でMongoDBの操作についてもう少し詳しく見ていきます。参照:MongoDB公式ドキュメント

Source:
https://www.digitalocean.com/community/tutorials/mongodb-findandmodify-example