1

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

4
  • What prevents you from just checking and choping messages size just before save? Commented Apr 16, 2013 at 8:39
  • @Vladimir I need use Capped Arrays (docs.mongodb.org/manual/tutorial/…) because it use mongoDB directly. Commented Apr 16, 2013 at 8:55
  • 1. Please, make it clear: are you using Java API, or query MongoDB directly from mongo shell? 2. Why couldn't you form DBCollection.udpate second argument to be like {"$push": ... $slice:-3}}}? Commented Apr 16, 2013 at 11:46
  • Yes Vladimir, I'm trying with "DBCollection.update" but I think this functionality would be implemented. Commented Apr 16, 2013 at 12:47

2 Answers 2

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!!!

Sign up to request clarification or add additional context in comments.

Comments

0

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().

1 Comment

It's the last resource I would like use! I'm trying to do with DBObject and BasicDBObject. Thank you btw!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.