简体   繁体   中英

Saving with Java springdata a mongoDB document with capped array ($slice and $sort)

I'm developing a log register using mongoDB and Java SpringData.

Here MongoDb capped sub-collection talks about mongoDB structure, but I would do with Java. The most important thing it's that I have a document with one or more fields and a capped array.

Is there some method or way in Java to do this?

My object it's like:

user = {
   name: String,
   latest_messages: [String] (capped to a 100 elements)
}

in Java:

public class MessageLog {
    private ObjectId id;
    private String name;
    private List<Message> messages;
}

Where:

public class Message{
    private String text;
    private String level;
    private Date date;
}

EDIT :

I'm using Java with Spring source (mongodb driver v2.10.1: http://central.maven.org/maven2/org/mongodb/mongo-java-driver/2.10.1/ )

I finally get the solution using this code:

// Define the search query
BasicDBObject searchQuery = new BasicDBObject().append("idU", idUser);

// To create the json query to modify
BasicDBObject logDocument = new BasicDBObject();

// Create the object and add it to a list (because the $each require a list)
List<DBObject> list = new ArrayList<DBObject>();
DBObject object = new BasicDBObject().append("text", logMessage.getText());
object.append("level", logMessage.getLevel())
object.append("date", logMessage.getDate());
list.add(object);

// Create the $sort and $slice query at the same time
logDocument.append(
    "$push",
    new BasicDBObject().append("logs", new BasicDBObject().append("$each", list).append("$sort", new BasicDBObject().append("date", 1))
            .append("$slice", -10)));

String json = "{findAndModify:\"collectionLog\", query:" + searchQuery.toString() + ", update: " + logDocument.toString() + ", upsert:true}";

try {
     getMongoTemplate().executeCommand(json);
} catch (Exception e) {
     System.out.println(e);
}

I hope it will be useful to someone else!!!

As you have noticed, MongoDB can't provide this functionality, so it has to be solved on the application layer.

Java by default doesn't support anything which works like a capped collection. But the collection library of the Apache Commons project has the class CircularFiFoBuffer which seems to be what you need. You create it with a max size. When you add a new element and it already is at the max size, the oldest element is discarded. Iteration order is from the oldest element to the newest.

A workaround without external libraries could be done with a LinkedList . Add new elements using the addFirst() method, check the size, and when it's larger than the desired maximum size, call removeLast().

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM