MongoDB中向数组插入文档概述

在这个教程中,我们将介绍如何在MongoDB中插入文档到数组,并将探讨$push$addToSet操作符的不同应用,用于将值添加到数组中。

首先,我们会创建一个示例数据库baeldung,以及一个集合orders,并往其中插入一些示例数据:

use baeldung;
db.createCollection(orders);

接下来,我们将使用insertMany方法向集合中添加更多文档:

db.orders.insertMany([
    {
        "customerId": 1023,
        "orderTimestamp": NumberLong("1646460073000"),
        "shippingDestination": "336, Street No.1 Pawai Mumbai",
        "purchaseOrder": 1000,
        "contactNumber":"9898987676",
        "items": [ 
            {
                "itemName": "BERGER",
                "quantity": 1,
                "price": 500
            },
            {
                "itemName": "VEG PIZZA",
                "quantity": 1,
                "price": 800
            } 
          ]
    },
    {
        "customerId": 1027,
        "orderTimestamp": NumberLong("1646460087000"),
        "shippingDestination": "445, Street No.2 Pawai Mumbai",
        "purchaseOrder": 2000,
        "contactNumber":"9898987676",
        "items": [ 
            {
               "itemName": "BERGER",
               "quantity": 1,
               "price": 500
            },
            {
               "itemName": "NON-VEG PIZZA",
               "quantity": 1,
               "price": 1200
            } 
          ]
    }
]);

如果插入成功,上述命令将输出类似以下的JSON:

{
    "acknowledged" : true,
    "insertedIds" : [
        ObjectId("622300cc85e943405d04b567"),
    ObjectId("622300cc85e943405d04b568")
    ]
}

至此,我们已经成功设置了数据库和集合。这些将在后续所有示例中使用。

3. 使用Mongo查询进行推入操作

MongoDB提供了多种类型的数组操作符来更新文档中的数组。MongoDB的$push操作符将值附加到数组的末尾。根据查询类型,我们可以使用updateOneupdateManyfindAndModify等方法与$push操作符配合。

现在让我们通过MongoDB shell查询来看一下使用$push操作符的情况:

db.orders.updateOne(
    {
        "customerId": 1023
    },
    {
        $push: {
            "items":{
                "itemName": "PIZZA MANIA",
                "quantity": 1,
                "price": 800
            }
        }
    });

此查询将返回以下文档:

{
    "acknowledged":true,
    "matchedCount":1,
    "modifiedCount":1
}

现在检查customerId为1023的文档。我们可以看到新项被添加到了“items”列表的末尾:

{
    "customerId" : 1023,
    "orderTimestamp" : NumberLong("1646460073000"),
    "shippingDestination" : "336, Street No.1 Pawai Mumbai",
    "purchaseOrder" : 1000,
    "contactNumber" : "9898987676",
    "items" : [
        {
            "itemName" : "BERGER",
            "quantity" : 1,
        "price" : 500
        },
    {
            "itemName" : "VEG PIZZA",
        "quantity" : 1,
        "price" : 800
    },
    {
        "itemName" : "PIZZA MANIA",
        "quantity" : 1,
        "price" : 800
        }
    ]
}

4. 使用Java驱动程序代码进行推入操作

到目前为止,我们讨论了MongoDB shell查询如何将文档推入数组。现在,我们将使用Java代码实现推入更新查询。

在执行更新操作之前,我们先连接到baeldung数据库中的orders集合:

mongoClient = new MongoClient("localhost", 27017);
MongoDatabase database = mongoClient.getDatabase("baeldung");
MongoCollection<Document> collection = database.getCollection("orders");

在这个例子中,我们连接的是运行在本地主机默认端口27017的MongoDB。

4.1. 使用DBObject

MongoDB Java驱动支持DBObject和BSON文档。DBObject是MongoDB旧版驱动的一部分,但在新版驱动中已弃用

现在,让我们看看Java驱动代码,如何将新值插入到数组:

DBObject listItem = new BasicDBObject("items", new BasicDBObject("itemName", "PIZZA MANIA")
  .append("quantity", 1)
  .append("price", 800));
BasicDBObject searchFilter = new BasicDBObject("customerId", 1023);
BasicDBObject updateQuery = new BasicDBObject();
updateQuery.append("$push", listItem);
UpdateResult updateResult = collection.updateOne(searchFilter, updateQuery);

在这段代码中,我们首先使用BasicDBObject创建了项目文档。根据searchQuery,将过滤集合中的文档,并将值推入数组。

4.2. 使用BSON文档

BSON文档是Java中访问MongoDB文档的新方法,它是基于新客户端堆栈构建的。org.bson.Document类更简单易用。

让我们使用org.bson.Document类将值推入“items”数组:

Document item = new Document()
  .append("itemName1", "PIZZA MANIA")
  .append("quantity", 1).append("price", 800);
UpdateResult updateResult = collection.updateOne(Filters.eq("customerId", 1023), Updates.push("items", item));

与使用DBObject的代码类似,BSON的实现也是相同的,更新效果也相同。这里,我们使用updateOne方法仅更新单个文档。

5. 使用$addToSet操作符

还可以使用$addToSet操作符将值推入数组。此操作符仅当值在数组中不存在时才添加,否则会忽略。而$push操作符则会根据条件过滤匹配后将值推入数组。

需要注意的是,$addToSet操作符在遇到重复项时不会将值推入数组。相反,$push操作符无论其他条件如何,都会将值推入数组。

5.1. 使用$addToSet操作符的shell查询

$addToSet操作符的MongoDB shell查询与$push操作符类似,但不会在数组中插入重复值。

现在,让我们查看使用$addToset将值推入数组的MongoDB查询:

db.orders.updateOne(
    {
        "customerId": 1023
    },
    {
        $addToSet: {
            "items":{
                "itemName": "PASTA",
                "quantity": 1,
                "price": 1000
            }
        }
    });

在这种情况下,输出如下:

{
    "acknowledged":true,
    "matchedCount":1,
    "modifiedCount":1
}

在这个例子中,我们使用了$addToSet操作符,只有当文档是唯一的时,才会将它推入“items”数组。

5.2. 使用Java驱动程序的$addToSet操作符

$addToSet操作符提供了与$push操作符不同的数组更新操作:

Document item = new Document()
  .append("itemName1", "PIZZA MANIA")
  .append("quantity", 1).append("price", 800);
UpdateResult updateResult = collection
  .updateOne(Filters.eq("customerId", 1023), Updates.addToSet("items", item));
System.out.println("updateResult:- " + updateResult);

在上面的代码中,我们首先创建了“item”文档,然后根据customerId过滤,使用updateOne方法尝试将“item”文档推入“items”数组。

6. 结论

本文介绍了如何使用$push$addToSet操作符将新值推入数组。首先,我们探讨了MongoDB shell查询中的$push操作符,随后讨论了相应的Java驱动代码实现。

所有案例的完整实现可在GitHub上找到。