使用$ in和upsert的MongoDB UpdateMany

时间:2015-09-04 12:31:07

标签: java mongodb mongodb-query mongodb-java

名为persons1的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开始计数,对于数组列表中的条目而不存在于persons1 Collection中?

问题描述:

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

{ "_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

1 个答案:

答案 0 :(得分:1)

&#34; catch&#34;这里_id的{​​{3}}个参数不会被解释为有效的&#34;填充物&#34;对于&#34; multi&#34;中的_id字段标记更新,这是你正在做的。所有_id值都将按默认ObjectId值填充,而不是&#34; upsert&#34;。

解决这个问题的方法是使用&#34; Bulk&#34;操作,使用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操纵为$in个对象,其中包含适用于UpdateOneModel的列表,以及所有&#34;个人&#34;使用一个响应在一个请求中发送更新,即使它们是&#34;技术上&#34;多个更新语句。

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

相关问题