使用Java向MongoDB插入文档并自动增加字段

3

我正在尝试使用Java进行一次事务性地插入一个带有序列号的文档。

类似于以下代码:

function getNextSequence(name) {
    var ret = db.counters.findAndModify(
        {
            query: { _id: name },
            update: { $inc: { seq: 1 } },
            new: true
        }
    );

    return ret.seq;
}
collection.insert({
    number: getNextSequence("userid"),
    name: "Some Name"
});

是否可以使用Java完成这个操作?最好使用官方的Java驱动程序。

4个回答

5

按照创建自增序列字段的文档,我们可以将其适配为使用Java MongoDB驱动程序的方案。

示例实现:

import java.net.UnknownHostException;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.MongoClient;

public class TestAutoIncrement {

private final static String DB_NAME = "MyTestDB";
private final static String TEST_COLLECTION = "testCollection";
private final static String COUNTERS_COLLECTION = "countersCollection";

public static DBCollection testCollection;
public static DBCollection countersCollection;

public static void main(String[] args) {

    try {
        MongoClient mongoClient = new MongoClient();
        DB database = mongoClient.getDB(DB_NAME);
        testCollection = database.getCollection(TEST_COLLECTION);
        countersCollection = database.getCollection(COUNTERS_COLLECTION);
    } catch (UnknownHostException e) {
        e.printStackTrace();
    }

    if (countersCollection.count() == 0) {
        createCountersCollection();
    }

    createTestCollection();
}

public static void createCountersCollection() {

    BasicDBObject document = new BasicDBObject();
    document.append("_id", "userid");
    document.append("seq", 0);
    countersCollection.insert(document);
}

public static Object getNextSequence(String name) {

    BasicDBObject searchQuery = new BasicDBObject("_id", name);
    BasicDBObject increase = new BasicDBObject("seq", 1);
    BasicDBObject updateQuery = new BasicDBObject("$inc", increase);
    DBObject result = countersCollection.findAndModify(searchQuery, null, null,
            false, updateQuery, true, false);

    return result.get("seq");
}

public static void createTestCollection() {

    BasicDBObject document = new BasicDBObject();
    document.append("_id", getNextSequence("userid"));
    document.append("name", "Sarah");
    testCollection.insert(document);

    document = new BasicDBObject();
    document.append("_id", getNextSequence("userid"));
    document.append("name", "Bob");
    testCollection.insert(document);

    document = new BasicDBObject();
    document.append("_id", getNextSequence("userid"));
    document.append("name", "Alex");
    testCollection.insert(document);
  }

}

特别需要注意的是findAndModify方法。在Java MongoDB驱动程序(2.12.4)中,该方法有4个不同的签名。
您必须使用其中一个,允许您传递query对象、update对象和returnNew布尔值(必须设置为true)。这是因为根据文档的说明:
默认情况下,返回的文档不包括对更新所做的修改。要返回带有对更新所做的修改的文档,请使用new选项。 我们需要返回带有对更新所做的修改的文档。

2

您无法在一个事务中执行此操作,即使您的JavaScript示例在执行插入之前也会执行findAndModify。

如果您想将文档插入到具有该集合中文档数量递增的集合中,则可以使用count方法并添加1。

    final DBCollection col = db.getCollection("myCollection");
    col.insert(new BasicDBObject("number", col.count() + 1));

或者使用一个单独的“计数器”集合,通过使用findAndModify()替代count()方法来实现计数。


1

就像Alex所写的那样,但是这段代码适用于3.x版本。

import com.mongodb.*;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;

public class TestAutoIncrement {

     private final static String DB_NAME = "MyTestDB";
     private final static String TEST_COLLECTION = "testCollection";
     private final static String COUNTERS_COLLECTION = "countersCollection";

     private static MongoCollection<Document> testCollection;
     private static MongoCollection<Document> countersCollection;

public static void main(String[] args) {

    MongoClient mongoClient = new MongoClient();
    MongoDatabase database = mongoClient.getDatabase(DB_NAME);
    testCollection = database.getCollection(TEST_COLLECTION);
    countersCollection = database.getCollection(COUNTERS_COLLECTION);

    if (countersCollection.count() == 0) {
        createCountersCollection();
    }

    createTestCollection();
    mongoClient.close();
}

public static void createCountersCollection() {

    Document document = new Document();
    document.append("_id", "userid");
    document.append("seq", 1);
    countersCollection.insertOne(document);
}

public static Object getNextSequence(String name) {

    Document searchQuery = new Document("_id", name);
    Document increase = new Document("seq", 1);
    Document updateQuery = new Document("$inc", increase);
    Document result = countersCollection.findOneAndUpdate(searchQuery, updateQuery);

    return result.get("seq");
}

public static void createTestCollection() {

    Document document = new Document();
    document.append("_id", getNextSequence("userid"));
    document.append("name", "Dinah");
    testCollection.insertOne(document);

    document = new Document();
    document.append("_id", getNextSequence("userid"));
    document.append("name", "Jonny");
    testCollection.insertOne(document);

    document = new Document();
    document.append("_id", getNextSequence("userid"));
    document.append("name", "Brody");
    testCollection.insertOne(document);
}

}

1

试试这个:

DBCollection collection = database.getCollection("testCollection");
// create an increment query
DBObject modifier = new BasicDBObject("counter", 1);
DBObject incQuery = new BasicDBObject("$inc", modifier);
// create a search query
DBObject searchQuery = new BasicDBObject("name", "someName");
// increment a counter value atomically
DBObject res = collection.findAndModify(searchQuery, incQuery);

这将更新相同的对象,我需要一些插入新对象的东西,其中一个字段每个新对象都增加了一个。它们应该看起来像这样{name:"name", number:1},{name="name", number:2},{name="someothername",number:3}。 - Idar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接