使用 Java 批量更新 MongoDB 中的文档

Mehvish Ashiq 2023年10月12日
  1. 先决条件
  2. 使用 Java 批量更新 MongoDB 中的文档
  3. 使用 updateMany() 通过向现有文档添加新字段来执行批量更新
  4. 使用 updateMany() 对匹配过滤器的多个文档中的现有字段执行批量更新
  5. 使用 updateMany() 对匹配过滤器的嵌入文档执行批量更新
  6. 使用 bulkWrite() API 更新与过滤查询匹配的现有文档
使用 Java 批量更新 MongoDB 中的文档

本教程是关于使用 Java 驱动程序在 MongoDB 中执行文档的批量更新。我们还将学习如何通过添加新字段、更改现有字段或数组的值或删除文档来进行更新。

先决条件

对于本教程,我们将使用你必须遵循的以下工具。

  1. Java(我们使用的是 Java 18.0.1.1)
  2. MongoDB 服务器(我们使用的是 MongoDB 5.0.8)
  3. 代码编辑器或任何 Java IDE(我们使用的是 Apache NetBeans IDE 13)
  4. 使用 Maven 或 Gradle 的 Mongo Java Driver Dependencies; 我们在 Maven 中使用它

使用 Java 批量更新 MongoDB 中的文档

当我们需要更新数据库中的多个文档时,批量更新很有用。现在,问题是,我们要如何更新文档?

我们是否想通过添加新字段、更新现有字段或数组的值或删除文档来进行更新?要了解所有这些场景,让我们创建一个集合并插入两个文档。

创建集合:

db.createCollection('supervisor');

插入第一个文档:

db.supervisor.insertOne(
    {
          "firstname": "Mehvish",
          "lastname": "Ashiq",
          "gender": "Female",
          "contact" : {
              "email":"mehvishofficial@gmail.com",
              "phone" : [
                  {
                      "type" : "official",
                      "number" : "123456789"
                  },
                  {
                       "type" : "personal",
                       "number" : "124578369"
                  },
               ]
          },
          "entries" : [
              { "_id" : 1, "itemsperday" : [ 1,3,4,5,6,7 ] },
              { "_id" : 2, "itemperday" : [ 2,3,4,5,2,7 ] },
              { "_id" : 3, "itemperday" : [ 5,0,0,4,0,1 ] }
           ]
    }
);

插入第二个文件:

db.supervisor.insertOne(
    {
          "firstname": "Tahir",
          "lastname": "Raza",
          "gender": "Male",
          "contact" : {
              "email":"tahirraza@gmail.com",
              "phone" : [
                  {
                      "type" : "official",
                      "number" : "123478789"
                  },
                  {
                       "type" : "personal",
                       "number" : "122378369"
                  },
               ]
          },
          "entries" : [
              { "_id" : 1, "itemsperday" : [ 4,5,6,7,4,6 ] },
              { "_id" : 2, "itemperday" : [ 2,3,2,7,5,2 ] },
              { "_id" : 3, "itemperday" : [ 5,0,0,1,0,0 ] }
           ]
    }
);

填充集合后,你可以使用 db.supervisor.find().pretty(); 查看插入的文档。我们将从简单的解决方案开始,然后转向一些棘手但有趣的解决方案。

使用 updateMany() 通过向现有文档添加新字段来执行批量更新

示例代码:

// write your package where you want to save your source file
package com.voidtesting.javamongobulkupdateexample;

// import necessary libraries
import com.mongodb.BasicDBObject;
import com.mongodb.MongoException;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;

// Example_1
public class Example_1 {
  // main method
  public static void main(String[] args) {
    // Replace the connection string with your own connection string
    var uri = "mongodb://localhost:27017";

    // try block
    try (MongoClient mongoClient = MongoClients.create(uri)) {
      // print message if connection is successfully established
      System.out.println("Connected successfully to server.");

      // get the specified database from the MongoDB server
      MongoDatabase database = mongoClient.getDatabase("bulkUpdate");

      // get the specified collection from the selected database
      MongoCollection<Document> collection = database.getCollection("supervisor");

      // update documents by adding a new field and its value
      collection.updateMany(
          new BasicDBObject(), new BasicDBObject("$set", new BasicDBObject("status", "Good")));

      // print a new line
      System.out.println();

      // iterate over all documents of the selected collection
      // to print in Java IDE
      collection.find().forEach(doc -> {
        System.out.println(doc.toBsonDocument());
        System.out.println();
      }); // end forEach

    } // end try block

    // print error if unable to execute a command
    catch (MongoException error) {
      System.err.println("An error occurred while running a command: " + error);
    } // end catch block

  } // end main method
} // end Example_1

输出:

{
    "_id": {"$oid": "62a866e592fd89ad9c4932ed"},
    "firstname": "Mehvish",
    "lastname": "Ashiq",
    "gender": "Female",
    "contact": {
        "email": "mehvishofficial@gmail.com",
        "phone": [
            { "type": "official", "number": "123456789"},
            {"type": "personal", "number": "124578369"}
         ]
     },
     "entries": [
         {"_id": 1.0, "itemsperday": [1.0, 3.0, 4.0, 5.0, 6.0, 7.0]},
         {"_id": 2.0, "itemperday": [2.0, 3.0, 4.0, 5.0, 2.0, 7.0]},
         {"_id": 3.0, "itemperday": [5.0, 0.0, 0.0, 4.0, 0.0, 1.0]}
     ],
     "status": "Good"
}

{
    "_id": {"$oid": "62a8670192fd89ad9c4932ee"},
    "firstname": "Tahir",
    "lastname": "Raza",
    "gender": "Male",
    "contact": {
        "email": "tahirraza@gmail.com",
        "phone": [
            {"type": "official", "number": "123478789"},
            {"type": "personal", "number": "122378369"}
         ]
     },
     "entries": [
         {"_id": 1.0, "itemsperday": [4.0, 5.0, 6.0, 7.0, 4.0, 6.0]},
         {"_id": 2.0, "itemperday": [2.0, 3.0, 2.0, 7.0, 5.0, 2.0]},
         {"_id": 3.0, "itemperday": [5.0, 0.0, 0.0, 1.0, 0.0, 0.0]}
     ],
     "status": "Good"
}

我们已经为你格式化了输出(如上所示),但你将在 IDE 上每行看到一个文档。我们也可以使用 db.supervisor.find().pretty(); 在 mongo shell 上查看更新的文档。

对于此示例代码,我们使用 mongo 集合对象的 updateMany() 方法,该方法接受 filter 查询和 update 语句来更新匹配的文档。在这里,我们不是过滤文档,而是向所有现有文档添加一个名为 status 的新字段(参见上面给出的输出)。

使用 updateMany() 对匹配过滤器的多个文档中的现有字段执行批量更新

示例代码:

// write your package where you want to save your source file
package com.voidtesting.javamongobulkupdateexample;

// import necessary libraries
import static com.mongodb.client.model.Filters.eq;
import static com.mongodb.client.model.Updates.combine;
import static com.mongodb.client.model.Updates.set;

import com.mongodb.MongoException;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;

// Example_2
public class Example_2 {
  // main method
  public static void main(String[] args) {
    // Replace the connection string with your own connection string
    var uri = "mongodb://localhost:27017";

    // try block
    try (MongoClient mongoClient = MongoClients.create(uri)) {
      // print message if connection is successfully established
      System.out.println("Connected successfully to server.");

      // get the specified database from the MongoDB server
      MongoDatabase database = mongoClient.getDatabase("bulkUpdate");

      // get the specified collection from the selected database
      MongoCollection<Document> collection = database.getCollection("supervisor");

      // update the filtered documents by updating the existing field
      collection.updateMany(eq("gender", "Female"), combine(set("gender", "F")));
      collection.updateMany(eq("gender", "Male"), combine(set("gender", "M")));

      System.out.println();
      // iterate over all documents of the selected collection
      // to print in Java IDE
      collection.find().forEach(doc -> {
        System.out.println(doc.toBsonDocument());
        System.out.println();
      }); // end forEach

    } // end try block

    // print error if unable to execute a command
    catch (MongoException error) {
      System.err.println("An error occurred while running a command: " + error);
    } // end catch block

  } // end main method
} // end Example_2

输出:

{
    "_id": {"$oid": "62a866e592fd89ad9c4932ed"},
    "firstname": "Mehvish",
    "lastname": "Ashiq",
    "gender": "F",
    "contact": {
        "email": "mehvishofficial@gmail.com",
        "phone": [
            { "type": "official", "number": "123456789"},
            {"type": "personal", "number": "124578369"}
         ]
     },
     "entries": [
         {"_id": 1.0, "itemsperday": [1.0, 3.0, 4.0, 5.0, 6.0, 7.0]},
         {"_id": 2.0, "itemperday": [2.0, 3.0, 4.0, 5.0, 2.0, 7.0]},
         {"_id": 3.0, "itemperday": [5.0, 0.0, 0.0, 4.0, 0.0, 1.0]}
     ],
     "status": "Good"
}

{
    "_id": {"$oid": "62a8670192fd89ad9c4932ee"},
    "firstname": "Tahir",
    "lastname": "Raza",
    "gender": "M",
    "contact": {
        "email": "tahirraza@gmail.com",
        "phone": [
            {"type": "official", "number": "123478789"},
            {"type": "personal", "number": "122378369"}
         ]
     },
     "entries": [
         {"_id": 1.0, "itemsperday": [4.0, 5.0, 6.0, 7.0, 4.0, 6.0]},
         {"_id": 2.0, "itemperday": [2.0, 3.0, 2.0, 7.0, 5.0, 2.0]},
         {"_id": 3.0, "itemperday": [5.0, 0.0, 0.0, 1.0, 0.0, 0.0]}
     ],
     "status": "Good"
}

此代码示例与上一个示例类似,但我们正在更新与过滤器匹配的所有文档中特定字段的值。

我们使用 updateMany()gender 等于 Femalegender 等于 Male 的所有文档执行批量更新。我们将 "gender": "Female""gender": "Male" 分别更改为 "gender":"F""gender":"M"

到目前为止,我们已经了解了如何使用 updateMany() 方法添加新字段或更新第一级现有字段的值。接下来,我们将学习使用 updateMany() 对满足过滤器查询的嵌入式文档进行批量更新。

使用 updateMany() 对匹配过滤器的嵌入文档执行批量更新

示例代码:

// write your package where you want to save your source file
package com.voidtesting.javamongobulkupdateexample;

// import necessary libraries
import com.mongodb.MongoException;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.UpdateOptions;
import org.bson.Document;
import org.bson.conversions.Bson;

// Example_3
public class Example_3 {
  // main method
  public static void main(String[] args) {
    // Replace the connection string with your own connection string
    var uri = "mongodb://localhost:27017";

    // try block
    try (MongoClient mongoClient = MongoClients.create(uri)) {
      // print message if connection is successfully established
      System.out.println("Connected successfully to server.");

      // get the specified database from the MongoDB server
      MongoDatabase database = mongoClient.getDatabase("bulkUpdate");

      // get the specified collection from the selected database
      MongoCollection<Document> collection = database.getCollection("supervisor");
      // filter
      Bson where = new Document().append("contact.phone.type", "official");
      // update
      Bson update = new Document().append("contact.phone.$.type", "assistant");
      // set
      Bson set = new Document().append("$set", update);

      // update collection
      collection.updateMany(where, set, new UpdateOptions());

      // iterate over all documents of the selected collection
      // to print in Java IDE
      collection.find().forEach(doc -> {
        System.out.println(doc.toBsonDocument());
        System.out.println();
      }); // end forEach

    } // end try block

    // print error if unable to execute a command
    catch (MongoException error) {
      System.err.println("An error occurred while running a command: " + error);
    } // end catch block

  } // end main method
} // end Example_3

输出:

{
    "_id": {"$oid": "62a866e592fd89ad9c4932ed"},
    "firstname": "Mehvish",
    "lastname": "Ashiq",
    "gender": "F",
    "contact": {
        "email": "mehvishofficial@gmail.com",
        "phone": [
            { "type": "assistant", "number": "123456789"},
            {"type": "personal", "number": "124578369"}
         ]
     },
     "entries": [
         {"_id": 1.0, "itemsperday": [1.0, 3.0, 4.0, 5.0, 6.0, 7.0]},
         {"_id": 2.0, "itemperday": [2.0, 3.0, 4.0, 5.0, 2.0, 7.0]},
         {"_id": 3.0, "itemperday": [5.0, 0.0, 0.0, 4.0, 0.0, 1.0]}
     ],
     "status": "Good"
}

{
    "_id": {"$oid": "62a8670192fd89ad9c4932ee"},
    "firstname": "Tahir",
    "lastname": "Raza",
    "gender": "M",
    "contact": {
        "email": "tahirraza@gmail.com",
        "phone": [
            {"type": "assistant", "number": "123478789"},
            {"type": "personal", "number": "122378369"}
         ]
     },
     "entries": [
         {"_id": 1.0, "itemsperday": [4.0, 5.0, 6.0, 7.0, 4.0, 6.0]},
         {"_id": 2.0, "itemperday": [2.0, 3.0, 2.0, 7.0, 5.0, 2.0]},
         {"_id": 3.0, "itemperday": [5.0, 0.0, 0.0, 1.0, 0.0, 0.0]}
     ],
     "status": "Good"
}

在这个 Java 程序中,我们使用 updateMany() 方法对匹配过滤器查询的嵌入文档执行批量更新。

在这里,我们将 contact.phone.type 的值从 official 更新为 assistant。要访问文档数组,我们使用位置运算符 ($) 来更新满足过滤器查询的第一个数组值。

在使用位置运算符时,我们还可以指定应该更新哪些数组元素。我们可以指定要更新的第一个、所有或特定的数组元素。

为了通过位置运算符指定数组元素,我们使用 dot notation,一种用于导航 BSON 对象的属性访问语法。我们通过以下方式使用位置运算符来更新第一个、所有或指定的数组元素。

  1. 我们使用位置运算符($)来更新满足过滤查询的数组的第一个元素,而数组字段必须是过滤查询的一部分才能使用位置运算符。

  2. 我们使用所有位置运算符($[])来更新数组的所有项目(元素)。

  3. 过滤位置运算符 ($[<identifier>]) 用于更新与过滤查询匹配的数组元素。在这里,我们必须在更新操作中包含数组过滤器,以告知哪些数组元素需要更新。

    请记住,<identifier> 是我们为数组过滤器指定的名称。此值必须以小写字母开头,并且只能包含字母数字字符。

使用 bulkWrite() API 更新与过滤查询匹配的现有文档

示例代码:

// write your package where you want to save your source file
package com.voidtesting.javamongobulkupdateexample;

// import necessary libraries
import com.mongodb.MongoException;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.DeleteOneModel;
import com.mongodb.client.model.UpdateManyModel;
import com.mongodb.client.model.WriteModel;
import java.util.ArrayList;
import java.util.List;
import org.bson.Document;

// Example_4
public class Example_4 {
  // main method
  public static void main(String[] args) {
    // Replace the connection string with your own connection string
    var uri = "mongodb://localhost:27017";

    // try block
    try (MongoClient mongoClient = MongoClients.create(uri)) {
      // print message if connection is successfully established
      System.out.println("Connected successfully to server.");

      // get the specified database from the MongoDB server
      MongoDatabase database = mongoClient.getDatabase("bulkUpdate");

      // get the specified collection from the selected database
      MongoCollection<Document> collection = database.getCollection("supervisor");

      // create object
      List<WriteModel<Document>> writes = new ArrayList<>();

      // delete the document matching the filter
      writes.add(new DeleteOneModel<>(new Document("firstname", "Tahir")));

      // update document matching the filter
      writes.add(new UpdateManyModel<>(new Document("status", "Good"), // filter
          new Document("$set", new Document("status", "Excellent")) // update
          ));

      // bulk write
      collection.bulkWrite(writes);

      // iterate over all documents of the selected collection
      // to print in Java IDE
      collection.find().forEach(doc -> {
        System.out.println(doc.toBsonDocument());
        System.out.println();
      }); // end forEach

    } // end try block
    catch (MongoException me) {
      System.err.println("An error occurred while running a command: " + me);
    } // end catch block
  } // end main method

} // end Example_4

输出:

{
    "_id": {"$oid": "62a866e592fd89ad9c4932ed"},
    "firstname": "Mehvish",
    "lastname": "Ashiq",
    "gender": "F",
    "contact": {
        "email": "mehvishofficial@gmail.com",
        "phone": [
            {"type": "assistant", "number": "123456789"},
            {"type": "personal", "number": "124578369"}
        ]
     },
     "entries": [
         {"_id": 1.0, "itemsperday": [1.0, 3.0, 4.0, 5.0, 6.0, 7.0]},
         {"_id": 2.0, "itemperday": [2.0, 3.0, 4.0, 5.0, 2.0, 7.0]},
         {"_id": 3.0, "itemperday": [5.0, 0.0, 0.0, 4.0, 0.0, 1.0]}
     ],
     "status": "Excellent"
}

在此示例中,我们使用 bulkWrite()API 一次执行多个操作(删除和更新)。DeleteOneModel() 用于删除匹配过滤器的文档,而我们使用 UpdateManyModel() 更新所有匹配过滤器的文档中已存在字段的值。

作者: Mehvish Ashiq
Mehvish Ashiq avatar Mehvish Ashiq avatar

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

LinkedIn GitHub Facebook