Insert document into mongodb with autoincrement field from java

I am trying to insert a document with sequence number in one transaction from java.

Something similar to this:

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"
});

      

Can this be done from java? Preferably with the official java driver.

+3


source to share


4 answers


By following the documentation for creating an automatic incremental sequence field , we will adapt it for use in Java using the Java MongoDB Driver .

Implementation example:

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);
  }

}

      



Particular attention should be paid to the methodfindAndModify

. In Java MongoDB driver (2.12.4), the method is available with 4 different signatures.
You should use one that allows an object to be passed query

, update

and a returnNew

boolean (which should be set to true

).

This is because according to the documentation :
By default, the checked out document does not include the changes made in the update. Use the new option to check in the document with the changes made in the update.

We need to check in the document with the changes made in the update.

+5


source


Try the following:



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);

      

+1


source


You cannot accomplish this in a single transaction, and even your javascript example does findAndModify before doing the insert.

If you want to insert documents into a collection with increasing number of documents from that collection, you can use the count method and add 1.

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

      

Or, using a separate collection of "counters" using findAndModify () instead of count ()

+1


source


as Alex wrote, but this code is suitable for 3.x versions

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


source







All Articles