0

I have a collection of the type :

{
  "_id" : ObjectId("51f1fcc08188d3117c6da351"),
  "cust_id" : "abc123",
  "ord_date" : ISODate("2012-10-03T18:30:00Z"),
  "status" : "A",
  "price" : 25,
  "items" : [{
  "sku" : "ggg",
  "qty" : 7,
  "price" : 2.5
}, {
  "sku" : "ppp",
  "qty" : 5,
  "price" : 2.5
}]
}

I want to fetch only the "items" object whose "items.qty">5 and and"items.sku"=="ggg".

I applied Map reduce:

cmd { "mapreduce" : "orders" , "map" : "function map(){var items_out={items:[]};for(i in this.items){items_out.items.push(this.items[i].sku);};emit(this._id,[items_out]);}" , "reduce" : "function reduce(key,values){return {'result':values};}" , "verbose" : true , "out" : { "replace" : "map_reduce"} , "query" : { "$where" : "return this.items.some(function(entry){return entry.qty>5})&&this.items.some(function(entry){return entry.sku=='ggg'})"}}, 

but I am getting all the sku values something like this:

{ "data": [  {     "items": [     "ggg",      "ppp"     ]     }    ]}

Whereas it should give only ggg as this is the only value matching criteria.

Janelle
  • 69
  • 9
Phalguni Mukherjee
  • 623
  • 3
  • 11
  • 29
  • 2
    Why would you do this with MR? You can just as easily do this with gthe aggregation framework, also why use the `$where` you should be using `$elemMatch` – Sammaye Jul 29 '13 at 12:50

1 Answers1

0

Use the following command:

db.orders.aggregate(
{$unwind : "$items"},
{$match : {"items.qty": {$gt: 5 }}},
{$match : {"items.sku" : "ggg"}},
{$project : {_id:0, items:1}}
)
Sarath Nair
  • 2,828
  • 2
  • 21
  • 36
  • You will need to regroup the items, also you only need one match, also you can do the match first to make use of an index – Sammaye Jul 29 '13 at 13:36
  • @Sammaye I showed the example of one collection, but what I am actually doing is applying MR to multiple collection and storing it in a temp collection and than querying the temp for data. – Phalguni Mukherjee Jul 29 '13 at 17:20