MongoDB findAndModify()示例

时间:2020-02-23 14:40:50  来源:igfitidea点击:

MongoDB的findAndModify()方法根据输入的选择条件修改并返回单个文档。
默认情况下,返回的文档不显示更新的内容。
如果数据库中不存在符合条件的记录,则将upsert设置为true时将插入一条新记录。

MongoDB findAndModify()

mongodb findAndModify方法的语法如下。

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

参数说明如下。

查询:定义关于哪些记录需要修改的选择标准。

排序:确定在选择条件检索多个文档时应修改哪个文档。

新增:表示将显示修改后的文档。

字段:指定要返回的字段集。

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: "San Franceco"},
{ _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" : "San Franceco" }
{ "_id" : 2, "name" : "Polo", "color" : "White", "cno" : "H411", "speed" : 45, "mfdcountry" : "Japan" }
{ "_id" : 3, "name" : "Audi", "color" : "Black", "cno" : "H412", "speed" : 50, "mfdcountry" : "Germany" }

继续查找和修改的实际用法,我们描述了不同的可能性。

情况1:该文档存在于数据库中

db.car.findAndModify({
query: { name: "Alto" },
sort: { cno: 1 },
update: { $inc: { speed: 10 } },
})
  • 该查询在汽车收藏夹中找到一个文档,其中名称字段的值为Alto。

  • 排序以升序对查询结果进行排序。
    如果满足查询条件的文档有多个,则该方法将按此类排序选择第一个文档进行修改。

  • 更新将速度字段的值增加10。

  • 该方法返回为此更新选择的原始文档:

输出:

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

情况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
}

请注意,由于我们将new设置为true,因此速度显示为更新值45。
如果未设置,则速度字段将显示为20,尽管旧值在数据库中已更新。

情况3:upsert设置为true

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

输出:

db.car.find();
{ "_id" : 1, "name" : "Alto", "color" : "Red", "cno" : "H410", "speed" : 50, "mfdcountry" : "San Franceco" }
{ "_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的汽车名称不在数据库中,因此将在数据库中创建一个新文档。
如果指定了排序选项,则该方法将返回一个空文档{}。
如果不包括sort选项,则该方法返回null。

除此之外,还可以用于执行"排序和删除"操作。

如果删除字段设置为true,则具有指定条件的汽车名称将从数据库中删除。

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

输出:

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

remove字段设置为true,名称为" Alto"的文档将从数据库中删除。

MongoDB findAndModify Java示例

上面描述的操作都是使用mongo shell手动执行的。
可以在Java中以编程方式完成以下操作。

下载mongo驱动程序jar并将其添加到您的类路径中。

首先,我们需要使用Mongo客户端建立与mongodb服务器的连接。
应该为连接指定数据库名称作为参数。
如果该数据库不存在,将创建一个新数据库。

此后,我们将一些记录添加到数据库中并执行findAndModify操作,然后验证记录是否实际更新。

下面的程序适用于mongo java驱动程序版本2.x。

package com.theitroad.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 {
		//Get a new connection to the db assuming it is running.
		MongoClient mongoClient = new MongoClient("localhost");
		//use test as the database. Use your database here.
		DB db = mongoClient.getDB("test");

		DBCollection coll = db.getCollection("car");
		
		//insert some test data to start with.
		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 operation. Update colour to blue for cars having speed
		//< 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);
	}
}

输出:

//Test Data Before Insert
{ "_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"}

//Test Data After insert
{ "_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.theitroad.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 {
      //Get a new connection to the db assuming it is running.
      MongoClient mongoClient = new MongoClient("localhost");
      
      //use test as the database. Use your database here.
      MongoDatabase db = mongoClient.getDatabase("test");
 
      MongoCollection<Document> coll = db.getCollection("car");
       
      //insert some test data to start with.
      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 operation. Update color to blue for cars having 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<Document> coll) {
		FindIterable<Document> cursor = coll.find();
      
		for (Document d : cursor)
			System.out.println(d);
	}
}