title: Mongodb Aggregation : How to return only matching elements of an array
body: <p>In my mongoDB book collection I have documents structured as follow : </p>
  
  <pre><code>/* 0 */
  {
    "_id" : ObjectId("50485b89b30f1ea69110ff4c"),
  
    "publisher" : {
      "$ref" : "boohya",
      "$id" : "foo"
    },
    "displayName" : "Paris Nightlife",
    "catalogDescription" : "Some desc goes here",
    "languageCode" : "en",
    "rating" : 0,
    "status" : "LIVE",
    "thumbnailId" : ObjectId("50485b89b30f1ea69110ff4b"),
    "indexTokens" : ["Nightlife", "Paris"]
  }
  </code></pre>
  
  <p>I perform the following regex query to find all documents having one indexToken starting with "Par" : </p>
  
  <pre><code>{ "indexTokens" : { "$regex" : "^Par" , "$options" : "i"}}
  </code></pre>
  
  <p>If I select only the indexTokens field to be returned like this :</p>
  
  <pre><code>{ "indexTokens" : 1}
  </code></pre>
  
  <p>The resulting DBObject is  </p>
  
  <pre><code>{ "_id" : { "$oid" : "50485b89b30f1ea69110ff4c"} , "indexTokens" : [ "Nightlife" , "Paris"]}
  </code></pre>
  
  <p>What I would like to get is ONLY the token / tag that matched the regex (I don0t care about retrieving the document at this point, neither do I need all the tags of the matched document) </p>
  
  <p>Is this a case for the new Aggregation Framework relesed under MongoDB v2.2. ?</p>
  
  <p>If yes how do I modify my query so that the actual result would look like :</p>
  
  <p>{ "indexTokens" : ["Paris", "Paradise River", "Parma" , etc ....]}</p>
  
  <p>Bonus question (do you has teh codez) : How do I do it using the Java driver ? </p>
  
  <p>For now my java looks like : </p>
  
  <pre><code>DBObject query = new BasicDBObject("indexTokens", java.util.regex.Pattern.compile("^"+filter+"", Pattern.CASE_INSENSITIVE));
      BasicDBObject fields = new BasicDBObject("indexTokens",1);
      DBCursor curs = getCollection()
                      .find(query, fields)
                      .sort( new BasicDBObject( "indexTokens" , 1 ))
                      .limit(maxSuggestionCount);
  </code></pre>
  
  <p>Thx :) </p>
  
  <p>EDIT: </p>
  
  <p>As per your answers I modified my JAVA code as follow : </p>
  
  <pre><code>BasicDBObject cmdBody = new BasicDBObject("aggregate", "Book"); 
      ArrayList&lt;BasicDBObject&gt; pipeline = new ArrayList&lt;BasicDBObject&gt;(); 
  
      BasicDBObject match = new BasicDBObject("$match", new BasicDBObject("indexTokens", java.util.regex.Pattern.compile("^"+titleFilter+"", Pattern.CASE_INSENSITIVE)));
      BasicDBObject unwind = new BasicDBObject("$unwind", "$indexTokens");
      BasicDBObject match2 = new BasicDBObject("$match", new BasicDBObject("indexTokens", java.util.regex.Pattern.compile("^"+titleFilter+"", Pattern.CASE_INSENSITIVE)));
      BasicDBObject groupFilters = new BasicDBObject("_id",null);
      groupFilters.append("indexTokens", new BasicDBObject( "$push", "$indexTokens"));
      BasicDBObject group = new BasicDBObject("$group", groupFilters);
  
      pipeline.add(match);
      pipeline.add(unwind);
      pipeline.add(match2);
      pipeline.add(group);
  
      cmdBody.put("pipeline", pipeline); 
  
  
  
      CommandResult res = getCollection().getDB().command(cmdBody);
      System.out.println(res);
  </code></pre>
  
  <p>Which outputs </p>
  
  <pre><code>{ "result" : [ { "_id" :  null  , "indexTokens" : [ "Paris"]}] , "ok" : 1.0}
  </code></pre>
  
  <p>This is genius ! </p>
  
  <p>Thanks a lot ! </p>