6

I'm using Java Driver 3.0 with MongoDB in order to send JSONs through a webservice.

When I want to convert a Document object (org.bson.Document) to JSON, I use obj.toJson(), and when I want to convert a JSON to a Document object, I use Document.parse(json).

However when I'm dealing with lists of Documents (represented like this in JSON:[{"field1":1, ...}, {"field1":2, ...}]), I can't figure out a clean way of doing these conversions.

So far, I've come up with these "hacks":

  • From List to JSON: I add the list of documents as a value of a field called "list" in a bigger document. I convert this big document to JSON, and remove what I don't need from the obtained String.

    public String toJson(List<Document> docs){
        Document doc = new Document("list", docs);
        String json = doc.toJson();
        return json.substring(json.indexOf(":")+2, json.length()-1);
    }
    
  • From JSON to List: I do the opposite by adding this "list" field to the JSON, converting it to a Document and getting only the value of this field from the Document.

    public static List<Document> toListOfDocuments(String json){
        Document doc = Document.parse("{ \"list\":"+json+"}");
        Object list = doc.get("list");
        if(list instanceof List<?>) {
            return (List<Document>) doc.get("list");
        }
        return null ;
    }
    

I also tried to use another JSON serializer (I took Google's one), but it doesn't give the same result as the built-in toJson() method from the Document object, particularly for the "_id" field or the timestamps.

Is there any clean way of doing this?

Blakes Seven
  • 49,422
  • 14
  • 129
  • 135
Thematrixme
  • 318
  • 1
  • 4
  • 14

2 Answers2

9

The com.mongodb.util.JSON package is "still" not deprecated and does handle lists of DBObject quite well. You just need to do a little converting:

    MongoClient client = new MongoClient(new ServerAddress("192.168.2.4", 27017));

    MongoDatabase db = client.getDatabase("test");

    MongoCollection<Document> collection = db.getCollection("sample");

    MongoCursor<Document> iterator = collection.find().iterator();

    BasicDBList list = new BasicDBList();
    while (iterator.hasNext()) {
        Document doc = iterator.next();
        list.add(doc);
    }
    System.out.println(JSON.serialize(list));

And there is nothing wrong with adding that "list" to another DBObject wih the key "list" as used in your output. Otherwise you can delve into using another JSON parser and feeding each document from the cursor iterator into that.

It depends on the size of your input, but while this still works it sure looks a lot cleaner in code.

Blakes Seven
  • 49,422
  • 14
  • 129
  • 135
  • Thanks for the answer but I was wondering if there was a solution that is meant for the driver 3.0. But anyway, I didn't know I could use BasicDBList with Documents instead of DBObject, so thanks. I guess I can do the opposite to convert from JSON to List? – Thematrixme Jul 13 '15 at 11:33
  • @Thematrixme did you read the "is not deprecated" statement? That means it works with the current driver. There are other ways with external libraries. But no. There is no updated "util" package to work natively with BSON `Document` specifically. Just cast the types. – Blakes Seven Jul 13 '15 at 11:38
  • I know what deprecated means, I just fear this will be removed in the next releases, as you mentioned with "still not deprecated", and I would have liked a solution natively meant for the driver 3.0. However since no such thing exists yet, your answer seems to be the right one. Thanks! – Thematrixme Jul 13 '15 at 11:58
  • @Thematrixme I was not trying to be "condescending" here so please, I hope you are not taking it that way, and I used a term I therefore gave you the credit of undrestanding. My point is "not deprecated". Therefore worry about it when it is marked so and your builds start showing the warning. Like I also said, there are other JSON libraries where you can handle this, as well as some rich ( but very deep ) hooks into BSON document marshalling. I suspect there will be a "better way" in future driver releases. But for now, I say stick with what works and is what is "simple". Cheers. – Blakes Seven Jul 13 '15 at 12:20
1

There is solution for driver 3.0.

You follow the following steps:

BasicDBObject dbObject = (BasicDBObject) JSON.parse("yourJsonString");
MongoCollection<BasicDBObject> table = db.getCollection("collectionName", BasicDBObject.class);
table.insertOne(dbObject);
dur
  • 15,689
  • 25
  • 79
  • 125