{ "_id" : ObjectId("577b54816081dd32cd3e2d60"), "user" : ObjectId("577b54816081dd32cd3e2d5e"), "journals" : [ { "title" : "Journal Title2", "desc" : "desx2", "feeling" : 3, "date" : ISODate("2016-07-05T06:32:45.404Z"), "deleteFl" : true, "_id" : ObjectId("577b548d6081dd32cd3e2d64") }, { "title" : "Journal Title3", "desc" : "desx3", "feeling" : 3, "date" : ISODate("2016-07-05T06:49:00.156Z"), "deleteFl" : false, "_id" : ObjectId("577b585c6081dd32cd3e2d6d") }, { "title" : "Journal Title4", "desc" : "desx4", "feeling" : 3, "date" : ISODate("2016-07-05T06:49:06.700Z"), "deleteFl" : false, "_id" : ObjectId("577b58626081dd32cd3e2d70") } ] }
Above is my document structure
now, I need all the journal documents whose deleteFl = false.
I tried in this way using Java Mongo driver
getDatabase().getCollection("journals").find(and(eq("user", user), eq("journals.deleteFl", false)));
but still it gives me back all the documents including “deleteFl”: true. any help here ?
Answer
Actually, your query returns 1 document, because the data is inside 1 document. What you want is to limit the returning fields of a document (limit subdocuments).
Note: You can do that using elemMatch in the projection, to limit the fields returned by the query. But elemMatch will return just one subdocument. (I posted a deleted wrong answer using elemMatch)
When you want all subdocuments and only specific subdocuments from inside an array, you need to use the aggregation pipeline. Here is a tested code that does what you want (just change DB and colelction name):
MongoClient mongoClient = new MongoClient(); MongoDatabase db = mongoClient.getDatabase("test"); MongoCollection collection = db.getCollection("test"); Iterable<Document> output = collection.aggregate(asList( new BasicDBObject("$unwind", "$journals"), new BasicDBObject("$match", new BasicDBObject("journals.deleteFl", false)) )); for (Document dbObject : output) { System.out.println(dbObject); }