简体   繁体   中英

mongodb select sub document on the basis of search result of parent document

I have a chats collection witch sample document

{
    "_id" : ObjectId("57f95e8e385bb61c5cf2cd18"),
    //some other fields
    "messages" : [
            {
                    "sender" : "57ec1aaa0ffe16123439d52b",
                    "message" : "Hello!",
                    "sentTime" : "Oct 13, 2016 1:51:31 AM"
            },
            {
                    "sender" : "57ec1aaa0ffe16123439d52b",
                    "message" : "Hello!",
                    "sentTime" : "Oct 13, 2016 1:51:33 AM"
            }
    ]
}

I want to search the collection on the basis of _id field and only get the data of the messages sub-document as the query result using java driver for MongoDB as I want to Map to POJO array using Gson.

Desired Output:

[
        {
                "sender" : "57ec1aaa0ffe16123439d52b",
                "message" : "Hello!",
                "sentTime" : "Oct 13, 2016 1:51:31 AM"
        },
        {
                "sender" : "57ec1aaa0ffe16123439d52b",
                "message" : "Hello!",
                "sentTime" : "Oct 13, 2016 1:51:33 AM"
        }
]

How do I go with this using Java driver for MongoDB

We need to specify query and list of fields, here is an example of how to do it:

DB db = //get db

DBObject object = new BasicDBObject();
object.put("_id", new ObjectId("<some id>"));
DBObject fields = new BasicDBObject();
fields.put("messages", 1);
DBObject result = db.getCollection("test").findOne(object, fields);
System.out.println(result.get("messages"));

maybe it's a bit ugly, but it will work.

chats.aggregate(Arrays.asList(
    match(eq("_id", <your id here> )),
    unwind("$messages"),
    project(fields(excludeId(), 
                   computed("sender", "$messages.sender"), 
                   computed("message", "$messages.message"),
                   computed("sentTime", "$messages.sentTime")))
    )).forEach(printBlock);

printBlock just prints out each document (you can collect them to array there).

    Block<Document> printBlock = new Block<Document>() {
        @Override
        public void apply(final Document document) {
            System.out.println(document.toJson());
        }
    };  

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM