how to save and read map in mongoDB using java

i have a collection in mongo that contains 3 column as below:

{ 
"_id" : { "$oid" : "5396ad5de4b09ea27a641ed6"} , 
"word" : "test_word" , 
"doc_occurrence" : "'total':25,'sport':10" ,
 "total_occurrence" : "'total':32,'sport':15"
}

doc_occurrence and total_occurrence are Map. i insert documents to collection this way:

        private boolean add(String word, Map<String, Integer> docOccurrence, Map<String, Integer> totalOccurrence) {
    BasicDBObject document = new BasicDBObject();
    document.put("word", word);
    document.put("docOccurrence", docOccurrence);
    document.put("totalOccurrence", totalOccurrence);
    try {
        synchronized (LOCK_WRITE) {
            table.insert(WriteConcern.SAFE,document);


        }
    } catch (MongoException e) {
        logger.error("Could not insert new row to word_cat : {}", e.getMessage());
        return false;
    }
    return true;
}

i want to read maps from DB this way:

        BasicDBObject searchQuery = new BasicDBObject();
        searchQuery.put("word",word);
    try {
        DBCursor cursor = table.find(searchQuery);
        if (cursor.hasNext()) {
            DBObject doc = cursor.next();
            Map<String, Integer> map = (Map<String, Integer>)doc.get("docOccurrence"); // ClassCastException

but i get

java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Map

is there any way i cat read maps directly from DB? if not, what is altenative?

p.s: BSON convert map to String. in fact BSON keys must be String!

Answer

The problem here is that you have created your BSON object with the Map part placed in the “string” size of the constructor, so there is an implicit “stringify” in there in this invocation.

Wrapped as the sole argument to a BSON Object constructor then then Map serializes properly:

document.put("word", word);
document.put("docOccurrence", new BasicDBObject(docOccurrence));
document.put("totalOccurrence", new BasicDBObject(totalOccurrence));

The BasicDBObject class implements the AbstractMap interface and should be able to be used that way on data that is read. The rest of the code should work as expected.

Leave a Reply

Your email address will not be published. Required fields are marked *