mongodb - How to convert this map reduce in aggregate framework? -
i've still done map/reduce/finalize function using mongodb.
this how need mongodb executes aggregation:
db.house_results.mapreduce(function(){ emit(this.house_name.tolowercase(),this); },function(key,values){ var house = {name:key,address:"",description:"",photo:[],lat:0,lng:0,rooms:[]}; values.foreach(function(house_val) { /*address*/ if(house.address=="") house.address = house_val.house_address; /*photo*/ if(!house_val.photo in house.photo) house.photo.push(house_val.house_photo); /*description*/ if(house.description=="") house.description = house_val.house_description; /*lat - lng*/ if(house.lat==0 || house.lng==0){ var house_position = house_val.house_position; if(house_position && house_position.lat && house_position.lng){ house.lat = house_position.lat; house.lng = house_position.lng; } } if(house.lat==0 || house.lng==0){ if(house_val.house_lat && house_val.house_lng){ house.lat = house_val.house_lat; house.lng = house_val.house_lng; } } if(house_val.rooms) house.rooms.push(house_val.rooms); }); return house; }, { out : "map_reduce_house_test", finalize:function(key,house_val){ if(house_val.address==undefined){ // 1 result in map function -> reduce function ignored -> finalize solution var house = {name:key,address:"",description:"",photo:[],lat:0,lng:0,rooms:[]}; /*address*/ if(house.address=="") house.address = house_val.house_address; /*photo*/ if(!house_val.photo in house.photo) house.photo.push(house_val.house_photo); /*description*/ if(house.description=="") house.description = house_val.house_description; /*lat - lng*/ if(house.lat==0 || house.lng==0){ var house_position = house_val.house_position; if(house_position && house_position.lat && house_position.lng){ house.lat = house_position.lat; house.lng = house_position.lng; } } if(house.lat==0 || house.lng==0){ if(house_val.house_lat && house_val.house_lng){ house.lat = house_val.house_lat; house.lng = house_val.house_lng; } } if(house_val.rooms) house.rooms.push(house_val.rooms); return house; }else return house_val; } } );
is there way simplify functions and/or better same aggregation mongodb's function?
which fastest , simplier method?
thanks!
there isn't going on in mapreduce other taking first values various fields common grouping key , otherwise pushing other values onto arrays.
therefore same aggregation:
db.house_results.aggregate([ { "$group": { "_id": { "$tolower": "$house_name" }, "name": { "$first": { "$tolower": "$house_name" } }, "photo": { "$push": "$house_photo" }, "address": { "$first": "$house_address" }, "description": { "$first": "$house_description" }, "lat": { "$max": { "$cond": [ { "$gt": [ "$house_lat", "$house_position.lat" } }, "$house_lat", "$house_position.lat" } }, "lng": { "$max": { "$cond": [ { "$gt": [ "$house_lng", "$house_position.lng" } }, "$house_lng", "$house_position.lng" } }, "rooms": { "$push": "$house_rooms" } }} ])
the real difference there conditional handling of "lat" , "lng" output using $cond
operator.
noting "_id" , "name" have same thing in them, map reduce doing.
take @ aggregation operators reference, data should rather it's present form, appears de-normalized dump somewhere.
also reference, isn't affecting in case, wrong way write mapreduce. output "map" function different "reduce" function, notably arrays.
even though these have 1 element in them "should" emitted array element "map" function , treated if array element "reduce" function.
this because larger "grouping", not matching key values sent reduce function @ once, , reducer can called combine other values emitted "map" "reduce" function reduced output. how large data handling, , arrays run risk of output this, un-expected embedding of array within array:
[ [4,5,6], 7, 8, 9 ]
but covered in the documentation read carefully.
at rate, aggregation pipeline ( 1 stage) perform faster present operation. change data possible.
Comments
Post a Comment