2013-07-29 97 views
0

我有類型的集合:精確Reduce函數

{ 
    "_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 
}] 
} 

我只想獲取其「items.qty」> 5,並和「項目」對象「items.sku」 ==「GGG 」。

我申請的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'})"}}, 

但我讓所有的SKU值是這樣的:

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

而它應該只給ggg,因爲這是唯一的價值匹配條件。

+2

爲什麼你會與MR做到這一點?你可以用gthe聚合框架輕鬆做到這一點,爲什麼使用'$ where'你應該使用'$ elemMatch' – Sammaye

回答

0

使用以下命令:

db.orders.aggregate(
{$unwind : "$items"}, 
{$match : {"items.qty": {$gt: 5 }}}, 
{$match : {"items.sku" : "ggg"}}, 
{$project : {_id:0, items:1}} 
) 
+0

你需要重新組合項目,你也只需要一個匹配,你也可以做匹配首先利用索引 – Sammaye

+0

@Sammaye我展示了一個集合的例子,但我實際上做的是將MR應用於多個集合並將其存儲在一個臨時集合中,而不是查詢數據的臨時值。 –