Prasad Kharkar
Prasad Kharkar

Reputation: 13556

retrieve array from mongodb using java with mongodb api

I understand that there are many questions which as for the same and they are answered well. The problem is all those questions use MongoDBObject, MongoDBList to retrieve arrays. My problem is I am using http://api.mongodb.org/java/3.0/index.html?overview-summary.html api and I am having hard time retrieving array and adding elements to it. I have to use MongoCollection, MongoDatabase and MongoClient. I am trying to solve an assignment from mongodb course. The problem statement is to find an array and update it in mongod.

Here is what I have tried

      Document post = null; Bson filter = new Document("permalink",
      permalink); Bson projection = new Document("comments", true);
      List<Document> comments = postsCollection.find(filter)
      .projection(projection).into(new ArrayList<Document>());
      System.out.println(comments);

      post = postsCollection.find(Filters.eq("permalink",
      permalink)).first();

      Document newComment = new Document();

      newComment.append("author", name); newComment.append("body", body);
      if (email != null && (!email.equals(""))) {
      newComment.append("email", email); }

      comments.add(newComment);

      Bson filter2 = new Document("_id", post.get("_id"));
      System.out.println(comments); post =
      postsCollection.find(filter).first();

      postsCollection.updateOne(filter2, new Document("$unset",new
      Document("comments",true))); postsCollection.updateOne(filter2, new
      Document("$set", new Document( "comments", comments)));

This does not create a new comment. Instead, it creates another comments array in comments array itself. THe array should be updated in student

Here is the json data

{
"_id" : ObjectId("55d965eee60dd20c14e8573e"),
"title" : "test title",
"author" : "prasad",
"body" : "test body",
"permalink" : "test_title",
"tags" : [ 
    "test", 
    "teat"
],
"date" : ISODate("2015-08-23T06:19:26.826Z"),
"comments" : [ 
    {
        "_id" : ObjectId("55d965eee60dd20c14e8573e"),
        "comments" : [ 
            {
                "_id" : ObjectId("55d965eee60dd20c14e8573e"),
                "comments" : []
            }, 
            {
                "author" : "commented",
                "body" : "something in comment",
                "email" : "[email protected]"
            }
        ]
    }, 
    {
        "author" : "commented",
        "body" : "something in comment",
        "email" : "[email protected]"
    }
]

}

Upvotes: 8

Views: 21156

Answers (4)

ZZ 5
ZZ 5

Reputation: 1954

If you're forced to use older version of mongo driver and you can't use the method the MKP has mentioned, then you can copy the method itself.

Here it is as a Kotlin extension

import org.bson.Document
import java.lang.String.format

fun <T> Document.getList(key: String, clazz: Class<T>, defaultValue: List<T>): List<T> {
    val list = this.get(key, List::class.java)
    if (list == null) {
        return defaultValue
    }
    list.forEach {
        if (!clazz.isAssignableFrom(it!!::class.java)) {
            throw ClassCastException(format("List element cannot be cast to %s", clazz.getName()))
        }
    }
    return list as List<T>
}

Upvotes: 0

MKP
MKP

Reputation: 67

This is much simplified here!

version - mongo-java-driver-3.12.5.jar

comments = post.getList("comments", Document.class);

Upvotes: 4

Matt
Matt

Reputation: 1244

To avoid unchecked casts and linter warnings, along with writing your own loop, use the libary's get(final Object key, final Class<T> clazz) method:

List<Document> comments = posts.get("comments", docClazz)

where docClazz is something that you create once:

final static Class<? extends List> docClazz = new ArrayList<Document>().getClass();

Upvotes: 9

Nilesh Mistry
Nilesh Mistry

Reputation: 337

You need not write to this much code. Please check following code,

 public void addPostComment(final String name, final String email, final String body,
                           final String permalink) {
   Document post = findByPermalink(permalink);
   List<Document> comments = null;
   Document comment = new Document();
   if(post != null){
        comments = (List<Document>)post.get("comments");
        comment.append("author",name).append("body", body);

        if(email != null){
            comment.append("email", email);
        }
        comments.add(comment);
        postsCollection.updateOne(new Document("permalink",permalink), 
                                new Document("$set",new Document("comments",comments)));

        }
}

Upvotes: 5

Related Questions