1

I has the following json document in Mongo db. The show element will have several season elements which will also have several episodes elements that in turn have multiple questionEntry elements.

I want to return multiple questionElements where the questionElements metaTag entry equals my search. E.G. if a metaTag element equals my string the return it's parent questionEntry element and search across all elements nested in show.

{
"show":[
  {
     "season":[
        {
           "episodes":[
              {
                 "questionEntry":{
                    "id":1,
                    "info":{
                       "seasonNumber":1,
                       "episodeNumber":5,
                       "episodeName":"A Hero Sits Next Door"
                    },
                    "questionItem":{
                       "theQuestion":"What is the name of the ringer hired by Mr. Weed?",
                       "attachedElement":{
                          "type":1,
                          "value":""
                       }
                    },
                    "options":[
                       {
                          "type":1,
                          "value":"Johnson"
                       },
                       {
                          "type":1,
                          "value":"Hideo"
                       },
                       {
                          "type":1,
                          "value":"Guillermo"
                       }
                    ],
                    "answer":{
                       "questionId":1,
                       "answer":3
                    },
                    "metaTags":[
                       "Season 1",
                       "Episode 5",
                       "Trivia",
                       "Arya Stark",
                       "House Stark"
                    ]
                 }
              }
           ]
        }
     ]
   }
 ]
}

I'm usingthe latest Java Mongo driver in Windows 8.1 and using Mongodb 2.4.4. So my question is what is the best method to return a single or multiple qestionEntry element(s) over this entire show collection that match my search string?

Hopefully somebody here can help me with this.

EDIT:

private DB mongoDatabase;
private DBCollection mongoColl;
private DBObject dbObject;

// Singleton class
// Create client (server address(host,port), credential, options)
        mongoClient = new MongoClient(new ServerAddress(host, port), 
                Collections.singletonList(credential),
                options);

mongoDatabase = ClientSingleton.getInstance().getClient().getDB("MyDB");
2
  • 2.4.4 ?? That's really old version. Please update your mongo to 3.0 if possible. Commented Jul 23, 2015 at 5:26
  • @Jhanvi Hi it's a hosted mongodb that we don't have control of the version. Can you help with my query? Commented Jul 23, 2015 at 7:49

1 Answer 1

1

Please try the below :

 db.exp.aggregate([{"$redact":{"$cond": { if: {$gt:[ {"$size": {
 $setIntersection : [ { "$ifNull": [ "$metaTags", []]}, 
 ["House Stark"]]} } , 0 ]} , then:"$$PRUNE",
 else:"$$DESCEND" }}}]).pretty();

[OR]

EDIT :

db.exp.aggregate([{"$unwind":"$show"},
 {"$unwind":"$show.season"},
 {"$unwind":"$show.season.episodes"},
 {"$match" : {"show.season.episodes.questionEntry.metaTags":{"$in": 
   ["Trivia"]}}},
 {"$group":{"_id":"$_id","episodes":{"$push":"$show.season.episodes"}
]);

JAVA CODE :

    MongoClient client = new MongoClient();
    List<String> continentList = Arrays.asList(new String[]{"Trivia"});
    DB db = client.getDB("example");
    DBCollection coll = db.getCollection("exp");
    DBObject matchFields = new 
       BasicDBObject("show.season.episodes.questionEntry.metaTags", 
      new BasicDBObject("$in", continentList));
    DBObject groupFields = new BasicDBObject( "_id",
       "$_id").append("episodes", 
       new BasicDBObject("$push","$show.season.episodes"));
    DBObject unwindshow = new BasicDBObject("$unwind","$show");
    DBObject unwindsea = new BasicDBObject("$unwind", "$show.season");
    DBObject unwindepi = new BasicDBObject("$unwind", 
      "$show.season.episodes");
    DBObject match = new BasicDBObject("$match", matchFields);
    DBObject group = new BasicDBObject("$group", groupFields);      
    AggregationOutput output = 
    coll.aggregate(unwindshow,unwindsea,unwindepi,match,group);

    for (DBObject result : output.results()) {
         System.out.println(result);
         }
Sign up to request clarification or add additional context in comments.

7 Comments

thanks for your reply. I'll try that later. Also thanks for answering a previous related post of mine too :-)
I need to be able to return the whole parent element(s) of any meteTag element that match my search string using Java.
Please Check i have added few more things in my answer. Hope it resolves your issue :)
Many thanks, it's working but only for the first item in the metaTags array - well I mean only working for the search string "Season 1" which is the first item? Else it's not entering the loop, also getting a depreciated warning for collection.aggregate so I used @SurpessedWarning("depreciated")..!
I have executed the code in my machine and it perfectly works fine. If you can see i have used search string "Trivia" which is not the first element in the doucment you have given. I have used the same for testing purpose as well.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.