【问题标题】:MongoDB UpdateMany with $in and upsert带有 $in 和 upsert 的 MongoDB UpdateMany
【发布时间】:2015-11-30 14:50:19
【问题描述】:

名为 people1 的 Mongo 集合包含以下数据:

db.persons1.find().pretty();


{ "_id" : "Sims",    "count" : 32 }
{ "_id" : "Autumn",  "count" : 35 }
{ "_id" : "Becker",  "count" : 35 }
{ "_id" : "Cecile",  "count" : 40 }
{ "_id" : "Poole",   "count" : 32 }
{ "_id" : "Nanette", "count" : 31 }

现在通过 Java,我编写了代码来增加列表中存在的用户的计数

MongoClient mongoclient = new MongoClient("localhost", 27017);
MongoDatabase db = mongoclient.getDatabase("testdb1");
MongoCollection<Document> collection = db.getCollection("persons1");
List li = new ArrayList();
li.add("Sims");
li.add("Autumn");

collection.updateMany(
    in("_id",li),
    new Document("$inc", new Document("count", 1)),
    new UpdateOptions().upsert(true));

运行上面的java程序后,我的输出如下。

db.persons1.find().pretty();


{ "_id" : "Sims", "count" : 33 }
{ "_id" : "Autumn", "count" : 36 }
{ "_id" : "Becker", "count" : 35 }
{ "_id" : "Cecile", "count" : 40 }
{ "_id" : "Poole", "count" : 32 }
{ "_id" : "Nanette", "count" : 31 }

我的问题:是否可以插入并从 1 开始计数,用于 Array 列表中存在的条目而不存在于 person1 集合中?

问题描述:

之前的程序数据库包含以下详细信息:

{ "_id" : "Sims",    "count" : 33 }
{ "_id" : "Autumn",  "count" : 36 }
{ "_id" : "Becker",  "count" : 35 }
{ "_id" : "Cecile",  "count" : 40 }
{ "_id" : "Poole",   "count" : 32 }
{ "_id" : "Nanette", "count" : 31 }

示例 Java 代码:

MongoClient mongoclient = new MongoClient("localhost", 27017);
MongoDatabase db = mongoclient.getDatabase("testdb1");
MongoCollection<Document> collection = db.getCollection("persons1");
List li = new ArrayList();

// Entry already Present so required to increment by 1
li.add("Sims");

// Entry already Present so required to increment by 1
li.add("Autumn");

// Entry is NOT Present, hence insert into persons data base with "_id" as User1 and count as 1
li.add("User1");

// Entry is NOT Present, hence insert into persons data base with "_id" as User1 and count as 1
li.add("User2");

// Code to be written

从数据库中获取输出的代码应该是什么,如下所示:

{ "_id" : "Sims",    "count" : 34 } // Entry already Present, incremented by 1
{ "_id" : "Autumn",  "count" : 37 } // Entry already Present, incremented by 1
{ "_id" : "Becker",  "count" : 35 }
{ "_id" : "Cecile",  "count" : 40 }
{ "_id" : "Poole",   "count" : 32 }
{ "_id" : "Nanette", "count" : 31 }
{ "_id" : "User1",   "count" : 1 }  // Entry Not Present, start by 1
{ "_id" : "User2",   "count" : 1 }  // Entry Not Present, start by 1

【问题讨论】:

  • 据我所见,您建议的代码应该正确执行。那么结果中什么对您不起作用?
  • 我的代码不会插入新的 id,作为更新的一部分,我只包括增量运算符..如何包含 id 的列表。所以如果它在 arraylist 中找不到 id,它将插入计数作为一个,但 id 是从 mongo db 内部生成的。
  • 这不可能是真的。 1. _id 是“必填项”,必须始终插入。 2.您确实提供了一个列表和.updateMany() 方法“包装”以暗示“多”作为参数。以及你有“upsert”。如果您认为自己有不同,请显示结果以使其成为可重复的案例。
  • collection.updateMany(in("_id",li), new Document("$inc", new Document("count", 1).append("$set", new Document(" _id", li)))) , new UpdateOptions().upsert(true));
  • 代码应该如上吗?

标签: java mongodb mongodb-query mongodb-java


【解决方案1】:

这里的“捕获”是 _id$in 参数不会被解释为“多”标记更新中 _id 字段的有效“填充”,这就是您正在做的事情。默认情况下,所有_id 值都将填充ObjectId 值而不是“upsert”。

解决这个问题的方法是使用“批量”操作,在 Java 3.x 驱动程序中,您可以使用 BulkWrite 类和如下结构:

    MongoCollection<Document> collection = db.getCollection("persons1");

    List li = new ArrayList();

    li.add("Sims");
    li.add("User2");

    List<WriteModel<Document>> updates = new ArrayList<WriteModel<Document>>();

    ListIterator listIterator = li.listIterator();

    while ( listIterator.hasNext() ) {
        updates.add(
            new UpdateOneModel<Document>(
                new Document("_id",listIterator.next()),
                new Document("$inc",new Document("count",1)),
                new UpdateOptions().upsert(true)
            )
        );
    }

    BulkWriteResult bulkWriteResult = collection.bulkWrite(updates);

这会将您的基本List 操作为具有适合bulkWrite 的列表的UpdateOneModel 对象,并且所有“个人”更新都在一个请求中发送一个响应,即使它们是“技术上的”多个更新语句。

这是设置多个_id 键或通过$in 匹配通常与更新操作有效的唯一方法。

【讨论】:

  • 在执行上述代码时遇到这个问题...线程“main”java.lang.UnsupportedOperationException中的异常
  • @svsteja 对不起。 updates 对象列表的错误转换。坏习惯,我没有检查。固定。
  • @布雷克斯七..谢谢..上面的代码有效..是否可以使用spring data mongo实现相同的功能
  • @svsteja 如果您有不同的问题,那么Ask a new question。 Spring-mongo 使用与 MongoDB 3.x Java 驱动程序中引入的操作不同的操作,但相同的批量操作仍然可以通过早期的驱动程序方法或仅使用没有批量操作的 spring-mongo 更新方法。
猜你喜欢
  • 2018-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-23
  • 1970-01-01
  • 2019-01-07
相关资源
最近更新 更多