DevVeri.com

Boğulacaksan büyük veride boğul!

MongoDB ile MapReduce Kullanımı

MongoDB document-oriented mimariye sahip NoSQL veritabanıdır. MongoDB üzerinde bildiğimiz klasik veritabanlarındaki gibi tablo yapısına sahip değil. Verilerimizi BSON(Binary JSON) şeklinde tutuyor. Tablo yapısı yok onun yerine collectionlar mevcut. (bkz: MongoDB NoSQL Veritabanı)

MongoDB üzerinde MapReduce işlemleri javascript ile yapılmaktadır. Klasik veritabanlarındaki count, sum, having gibi işlemleri yapmak için MongoDB üzerinde MapReduce kullanıyoruz. (bkz: MapReduce Nedir?)

Örnek product collectionında bulunan verilerim aşağıdaki gibidir:

> db.product.find().pretty()
{
	"_id" : ObjectId("4faec33dd57e4ace158b7e9f"),
	"type" : "Shirt",
	"color" : "Green",
	"sizes" : {
		"L" : 2,
		"XL" : 3,
		"XXL" : 4
	},
	"price" : 10
}
{
	"_id" : ObjectId("4faec64bd57e4ace158b7ea0"),
	"type" : "Shirt",
	"color" : "Red",
	"sizes" : {
		"L" : 5,
		"XL" : 4,
		"XXL" : 4
	},
	"price" : 15
}
{
	"_id" : ObjectId("4faec65ad57e4ace158b7ea1"),
	"type" : "Shirt",
	"color" : "Yellow",
	"sizes" : {
		"L" : 1,
		"XL" : 3,
		"XXL" : 4
	},
	"price" : 25
}
{
	"_id" : ObjectId("4faf8768d001a2b51cf047a0"),
	"type" : "Sweat Shirt",
	"color" : "Black",
	"sizes" : {
		"L" : 1,
		"XL" : 3,
		"XXL" : 4
	},
	"price" : 20
}
{
	"_id" : ObjectId("4faf877ad001a2b51cf047a1"),
	"type" : "Sweat Shirt",
	"color" : "Blue",
	"sizes" : {
		"L" : 1,
		"XL" : 3,
		"XXL" : 4
	},
	"price" : 50
}
{
	"_id" : ObjectId("4faf878dd001a2b51cf047a2"),
	"type" : "Sweat Shirt",
	"color" : "Gray",
	"sizes" : {
		"L" : 1,
		"XL" : 3,
		"XXL" : 4
	},
	"price" : 25
}

MongoDB üzerinde MapReduce işlemlerini örneklerle anlatmak istiyorum.

Örnek 1 : Şimdi ürün tiplerine göre ürünlerin toplam fiyatını almak için örnek bir MapReduce işlemi yapalım.

map = function map() {
    //key olarak product type
    //value olarak ise obje icinde product price alanına gore mapliyoruz
    emit(this.type, {price:this.price} );
}

reduce = function reduce(key,values) {
    var result = { sumProductPrice: 0 };

    values.forEach(function(value) {
       result.sumProductPrice += value.price
    });

    return result;
}

> db.product.mapReduce(map, reduce, {out:"productMapReduce1"})
{
	"result" : "productMapReduce1",
	"timeMillis" : 377,
	"counts" : {
	"input" : 6,
	"emit" : 6,
	"reduce" : 2,
	"output" : 2
	},
	"ok" : 1,
}

> db.productMapReduce1.find()
{ "_id" : "Shirt", "value" : { "sumProductPrice" : 50 } }
{ "_id" : "Sweat Shirt", "value" : { "sumProductPrice" : 95 } }

Shirt ürünlerimizin toplamı 50, Sweat Shirt ise 95.

 

Örnek 2 : Ürünlerin sizelarına göre toplam kaç adet ürün bulunmakta onun hesaplamak için MapReduce örneği aşağıdaki gibidir.

map = function map(){
      var size;
      for (size in this.sizes) {
	  emit(size, this.sizes[size]);
      }
};

reduce = function reduce(key,values){
         var result = { count: 0 };

  	 values.forEach(function(value){
  		result.count += value;
  	 });

    return result;
}
> db.product.mapReduce(map,reduce,{out:"productMapReduce2"})
{
	"result" : "productMapReduce2",
	"timeMillis" : 2,
	"counts" : {
		"input" : 6,
		"emit" : 18,
		"reduce" : 3,
		"output" : 3
	},
	"ok" : 1,
}
> db.productMapReduce2.find()
{ "_id" : "L", "value" : { "count" : 11 } }
{ "_id" : "XL", "value" : { "count" : 19 } }
{ "_id" : "XXL", "value" : { "count" : 24 } }

 

Örnek 3 : Ürünlerin sizelarına göre bulunan ürünlerin toplam fiyatlarını hesaplamak için MapReduce örneği aşağıdaki gibidir.

map = function(){
	var size;
	for (size in this.sizes) {
	  emit(size, {size: this.sizes[size], price: this.sizes[size] * this.price });
	}
};

reduce = function reduce(key,values){

    var result = { sizeCount: 0, priceCount: 0 };

  	values.forEach(function(value){
  		result.sizeCount += value.size;
  		result.priceCount += value.price;
  	});

    return result;
}
> db.product.mapReduce(map,reduce,{out:"productMapReduce3"})
{
	"result" : "productMapReduce3",
	"timeMillis" : 67,
	"counts" : {
		"input" : 6,
		"emit" : 18,
		"reduce" : 3,
		"output" : 3
	},
	"ok" : 1,
}
> db.productMapReduce3.find()
{ "_id" : "L", "value" : { "sizeCount" : 11, "priceCount" : 215 } }
{ "_id" : "XL", "value" : { "sizeCount" : 19, "priceCount" : 450 } }
{ "_id" : "XXL", "value" : { "sizeCount" : 24, "priceCount" : 580 } }

L üründen 11 adet ve bu ürünlerin toplam fiyatı 215 TL
XL üründen 19 adet ve bu ürünlerin toplam fiyatı 450 TL
XXL üründen 24 adet ve bu ürünlerin toplam fiyatı 580 TL

 

Örnek 4 : Ürün tiplerine göre bulunan product collectionındaki idlerini bulmak için MapReduce örneği aşağıdaki gibidir.

map = function map() {
      emit(this.type, {productIds : [this._id]})
}

reduce = function reduce(key, values) {
    var productIds = [];

    var result = { productIds:[] };

    values.forEach(function(value) {
    	value.productIds.forEach(function(idValue){
    		productIds.push(idValue);
    	});
    });

    result.productIds = productIds;

    return result;
}

> db.product.mapReduce(map,reduce,{out:"productMapReduce4"})
{
	"result" : "productMapReduce4",
	"timeMillis" : 70,
	"counts" : {
		"input" : 6,
		"emit" : 6,
		"reduce" : 2,
		"output" : 2
	},
	"ok" : 1,
}

> db.productMapReduce4.find().pretty()
{
	"_id" : "Shirt",
	"value" : {
		"productIds" : [
			ObjectId("4faec33dd57e4ace158b7e9f"),
			ObjectId("4faec64bd57e4ace158b7ea0"),
			ObjectId("4faec65ad57e4ace158b7ea1")
		]
	}
}
{
	"_id" : "Sweat Shirt",
	"value" : {
		"productIds" : [
			ObjectId("4faf8768d001a2b51cf047a0"),
			ObjectId("4faf877ad001a2b51cf047a1"),
			ObjectId("4faf878dd001a2b51cf047a2")
		]
	}
}

 

Örnek 5: Hangi üründen hangi renklerden olduğunu bulabileceğeniz MapReduce aşağıdaki gibidir.

map = function map() {
      emit(this.type, {productColors :[this.color]});
}

reduce = function reduce(key, values) {
          var colors  = [];

          var results = { colors:[] };

          values.forEach(function(value){
   		value.productColors.forEach(function(colorValue){
   			colors.push(colorValue);
   	         });
          });

  results.colors = colors;

  return results;
}

> db.product.mapReduce(map,reduce,{out:"productMapReduce5"})
{
	"result" : "productMapReduce5",
	"timeMillis" : 6,
	"counts" : {
		"input" : 6,
		"emit" : 6,
		"reduce" : 2,
		"output" : 2
	},
	"ok" : 1,
}

> db.productMapReduce5.find().pretty()
{
	"_id" : "Shirt",
	"value" : {
		"colors" : [
			"Green",
			"Red",
			"Yellow"
		]
	}
}
{
	"_id" : "Sweat Shirt",
	"value" : {
		"colors" : [
			"Black",
			"Blue",
			"Gray"
		]
	}
}

Sonuç olarak bir çok işlemi MapReduce kullanarak MongoDB üzerinde yapabilirsiz. Eğer yapılan işlemleri trace etmek isterseniz “print(”)” fonksiyonu ile yapabilirsiniz en nihayetinde bir javascript yazıyorsunuz.

Kaynak: http://www.umitunal.net/mongodb-map-reduce-kullanimi/

, ,

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

This site uses Akismet to reduce spam. Learn how your comment data is processed.