블로그 이미지
윤영식
Full Stacker, Application Architecter, KnowHow Dispenser and Bike Rider

Publication

Category

Recent Post

2013. 8. 3. 17:52 MongoDB/MapReduce

10Gen에서 제공하는 Aggregation Framework에 대한 동영상 소개 예제를 실습해 본다 



1. 준비 

  - 10Gen 예제

  - http://media.mongodb.org/zips.json  데이터를 mongoimport 명령을 이용하여 넣기 

// zip.json 예제 mongoimport 

$ mongoimport --db bigdata --collection zipcodes --file zip.json

connected to: 127.0.0.1

Sat Aug  3 14:55:27.002 Progress: 1919717/2871006 66%

Sat Aug  3 14:55:27.002 19700 6566/second

Sat Aug  3 14:55:28.258 check 9 29470

Sat Aug  3 14:55:28.259 imported 29470 objects


// mongo shell

> use bigdata

switched to db bigdata

> show collections

system.indexes

zipcodes



2. 간단 수행

  - $group -> $match로 pipeline stream 처리

  - aggregate 메소드에 {} 객체를 넣고 콤마(,) 로 구분하면 왼쪽-> 오른쪽으로 pipeline 됨  

db.zipcodes.aggregate(

         { $group :

                         { _id : "$state",

                           totalPop : { $sum : "$pop" } } 

         },

         { $match : 

                         {totalPop : { $gte : 10*1000*1000 } }

         } );


SELECT state, SUM(pop) AS totalPop FROM zips GROUP BY state HAVING totalPop > (10*1000*1000)



3. 동영상 따라쟁이

  - 10Gen 동영상 예제


  - 샘플 수행 순서 : 일반 operator -find()같은- 와 aggregation framework operator 비교 수행 

 

  - $match == find와 같은 결과 그러나 다른 페러다임에서 처리된다는게 함정!

> db.zipcodes.aggregate({$match: {state:'NY', pop: {$gt:110000}}});

{

"result" : [

{

"city" : "BROOKLYN",

"loc" : [

-73.956985,

40.646694

],

"pop" : 111396,

"state" : "NY",

"_id" : "11226"

}

],

"ok" : 1

}


  - $match 후에 pipeline을 통하여 $sort 하기 : 단지 콤마(,)로 구분하면 된다 

> db.zipcodes.aggregate({$match: {state:'NY'}}, {$sort: {pop:-1}});


  - $match | $sort | $limit | $skip pipeline stream 처리 

> db.zipcodes.aggregate({$match: {state:'NY'}}, {$sort: {pop:-1}}, {$limit:5}, {$skip: 2});

{

"result" : [

{

"city" : "NEW YORK",

"loc" : [

-73.968312,

40.797466

],

"pop" : 100027,

"state" : "NY",

"_id" : "10025"

},

{

"city" : "JACKSON HEIGHTS",

"loc" : [

-73.878551,

40.740388

],

"pop" : 88241,

"state" : "NY",

"_id" : "11373"

},

{

"city" : "BROOKLYN",

"loc" : [

-73.914483,

40.662474

],

"pop" : 87079,

"state" : "NY",

"_id" : "11212"

}

],

"ok" : 1

}


  - 데이터에 $ 부호 사용하기 : 기존 document에는 population 필드가 존재하지 않는다 

> db.zipcodes.aggregate({$limit:1}, {$project: {city:1, state:1, pop:1, population:'$pop'}});

{

"result" : [

{

"city" : "ACMAR",

"pop" : 6055,

"state" : "AL",

"_id" : "35004",

"population" : 6055

}

],

"ok" : 1

}


$project가 하는 일은 무엇이 있을까?

- 필드 넣기 : Include fields from the original document.

- 계산된 필드 삽입 : Insert computed fields.

- 필드 이름 변경 : Rename fields.

- 서브도큐멘트에 대한 생성과 조작 : Create and populate fields that hold sub-documents.


  - 데이터에 $를 사용해 연산하여 결과를 얻기 

> db.zipcodes.aggregate({$limit:1}, {$project: {city:1, state:1, pop:1, population:'$pop', popSquared: {$multiply: ['$pop', '$pop']}} });

{

"result" : [

{

"city" : "ACMAR",

"pop" : 6055,

"state" : "AL",

"_id" : "35004",

"population" : 6055,

"popSquared" : 36663025

}

],

"ok" : 1

}

> 6055*6055

36663025


  - 기존 필드에 sub document 넣기  .' ' 사용한다 

> db.zipcodes.aggregate({$limit:1}, {$project: {city:1, state:1, population:'$pop', 'pop.Squared': {$multiply: ['$pop', '$pop']}} });

{

"result" : [

{

"city" : "ACMAR",

"pop" : {

"Squared" : 36663025

},

"state" : "AL",

"_id" : "35004",

"population" : 6055

}

],

"ok" : 1

}


  - pipeline 해보자  : $group -> $sort -> $limit 

> db.zipcodes.aggregate( {$group: {_id: '$state', pop: {$sum: '$pop'}}}, {$sort: {pop:-1}}, {$limit:3});

{

"result" : [

{

"_id" : "CA",

"pop" : 29760021

},

{

"_id" : "NY",

"pop" : 17990455

},

{

"_id" : "TX",

"pop" : 16986510

}

],

"ok" : 1

}


// 하나의 document마다 모든 city가 다 포함되어 결과 검출됨 (실습해 보삼^^)

> db.zipcodes.aggregate( {$group: {_id: '$state', pop: {$sum: '$pop'}, cities:{$addToSet: '$city'}}}, {$sort: {pop:-1}}, {$limit:3});


  - _id를 조합한 형태로 Pipeline 해보기 : $group -> $sort -> $limit 

> db.zipcodes.aggregate(

{$group: 

    {

        _id: {city: '$city', state: '$state'}, 

        pop: {$sum: '$pop'}, 

        avgPop: {$avg: '$pop'}

    }

},  

{$sort: {pop: -1}}, 

{$limit: 1}

)

// 결과 

{

"result" : [

{

"_id" : {

"city" : "CHICAGO",

"state" : "IL"

},

"pop" : 2452177,

"avgPop" : 52173.97872340425

}

],

"ok" : 1

}



<참조>

  - 예제 json 파일

zip.json

  - DZon의 Aggregation Framework 소개 기사

'MongoDB > MapReduce' 카테고리의 다른 글

[MongoDB] Aggregation Framework 이해하기  (0) 2013.08.03
[MongoDB] GridFS 사용하기  (0) 2013.02.23
[MongoDB] GridFS 개념잡기  (0) 2013.02.23
posted by 윤영식
2013. 8. 3. 16:08 MongoDB/MapReduce

MongoDB의 Aggregation 프레임워크에 대해서 알아보자. MongoDB의 Advance과정이라 말하고 싶다. MongoDB 전문가로 가고자 한다면 꼭 알아두어야 한다



1. Aggregation Framework

  - 10gen에서 이야기하는 집계프레임워크 개념

  - MongoDB의 Aggregation 목적은 Sharding 기반의 데이터에 대한 데이터 집계이다.

    



2. 개념 이해하기 

  - MongoDB v2.2 부터 나왔다

  - Shard를 통하여 BigData를 저장하고, Aggragation Framework을 통하여 BigData를 처리한다

  - Aggregation Framework의 2개의 중요 개념이 있다 : Pipelines, Expressions 

    + Pipelines : Unix의 pipe와 동일한다. mongodb pipeline 은 document를 stream화 한다. 또한 pipeline operators는 document의 stream을 처리한다. (마치 map-reducing과 같다)

NameDescription
$project

Reshapes a document stream. $project can rename, add, or remove fields as well as create computed values and sub-documents.  (참조Projection(π)은 관계 집합에서 원하지 않는 성분을 제거한다. 수학적인, 다른 dimension으로 mapping 한다는 것과 동일하다. Projection의 결과는 관계 집합이다)

$matchFilters the document stream, and only allows matching documents to pass into the next pipeline stage. $match uses standard MongoDB queries.
$limitRestricts the number of documents in an aggregation pipeline.
$skipSkips over a specified number of documents from the pipeline and returns the rest.
$unwind

Takes an array of documents and returns them as a stream of documents. (map=key:value 즉, map 만들기)

$groupGroups documents together for the purpose of calculating aggregate values based on a collection of documents.
$sortTakes all input documents and returns them in a stream of sorted documents.
$geoNearReturns an ordered stream of documents based on proximity to a geospatial point.

  ex) $project와 $unwind 되는 중간의 콤마(,) 가 pipeline되면서 stream방식으로 데이터가 처리되는 것이다 (OLAP의 dimension과 같음)

var p2 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
author : 1,
tags : 1,
pageViews : 1
}},
{ $unwind : "$tags" }

]});


   ex) Aggregation과 SQL 맵핑관계 : sql은 dbms안에서 하는 것이고, mongodb는 sharding 기반에서 하는것이다 

  


    + Expressions : input document를 수행한 계산값을 기반으로 output document를 생산하는 것이다. 

NameDescription
$addToSetReturns an array of all the unique values for the selected field among for each document in that group.
$firstReturns the first value in a group.
$lastReturns the last value in a group.
$maxReturns the highest value in a group.
$minReturns the lowest value in a group.
$avgReturns an average of all the values in a group.
$pushReturns an array of all values for the selected field among for each document in that group.
$sumReturns the sum of all the values in a group.



4. 실습하기 

// orders 컬렉션을 다음을 저장한다  

$ mongod --dbpath /home/mongodb/aggregation


// orders의 도큐먼트를 2번 동일하게 save 한다 

$ mongo

> db.orders.save({

   cust_id: "abc123",

   ord_date: ISODate("2012-11-02T17:04:11.102Z"),

   status: 'A',

   price: 50,

   items: [ { sku: "xxx", qty: 25, price: 1 },

            { sku: "yyy", qty: 25, price: 1 } ]

 });


//////////////////////////
// Where절
> db.orders.aggregate( [
    { $group: { _id: null,
                count: { $sum: 1 } } }
 ] );

// 결과 
{ "result" : [ { "_id" : null, "count" : 2 } ], "ok" : 1 }   

// sql
SELECT COUNT(*) AS count
FROM orders

////////////////////////
// sub query
> db.orders.aggregate( [
    { $group: { _id: { cust_id: "$cust_id",
                       ord_date: "$ord_date" } } },
    { $group: { _id: null, count: { $sum: 1 } } }
 ] )

{ "result" : [ { "_id" : null, "count" : 1 } ], "ok" : 1 }

// sql
SELECT COUNT(*)
FROM (SELECT cust_id, ord_date
      FROM orders
      GROUP BY cust_id, ord_date) as DerivedTable


  - Simple Aggregation Frameworkcount, distinct, group function 예제

///////////////////////////////////////////////////
// count
// find()에 대한 count() 펑션의 호출일 뿐이다 
> db.orders.find().count()
// aggregation 서비스이다. 
db.orders.count()
// aggregation 서비스이기 때문에 operation이 들어간다 
db.orders.count({status:'A'})
 
///////////////////////////////////////////////////
// 샘플 save 
db.dowonDB.save({a:1})
db.dowonDB.save({a:1})
db.dowonDB.save({a:2})
db.dowonDB.save({a:3})

db.dowonDB.count()
4
db.dowonDB.count({a:1})
2

///////////////////////////////////////////////////
db.dowonDB.distinct('a')
[ 1, 2, 3 ]

또는

// runCommand 계정권한를 가지고 수행하는 shell 명령
db.runCommand({'distinct':'dowonDB', 'key':'a'})
{
"values" : [
1,
2,
3
],
"stats" : {
"n" : 4,
"nscanned" : 4,
"nscannedObjects" : 4,
"timems" : 0,
"cursor" : "BasicCursor"
},
"ok" : 1
}

///////////////////////////////////////////////////
// group
db.dowonDB.save({dept_id: 1, salary: 1})
db.dowonDB.save({dept_id: 1, salary: 2})
db.dowonDB.save({dept_id: 1, salary: 3})
db.dowonDB.save({dept_id: 2, salary: 10})
db.dowonDB.save({dept_id: 2, salary: 12})
db.dowonDB.save({dept_id: 2, salary: 16})
db.dowonDB.save({dept_id: 3, salary: 4})
db.dowonDB.save({dept_id: 3, salary: 1})

// map 값이 distinct를 의미 : key 값이 map이 된다 
// reduce는 코딩 즉 function이다. 즉, 비즈니스 펑션이다 
> db.dowonDB.group(
 { key: {'dept_id': true},
   reduce: function(obj, prev) { prev.sum += obj.salary },
   initial: {sum: 0}
 });

// 결과
[
{
"dept_id" : null,
"sum" : NaN
},
{
"dept_id" : 1,
"sum" : 6
},
{
"dept_id" : 2,
"sum" : 38
},
{
"dept_id" : 3,
"sum" : 5
}
]

또는 condition 조건절 줌 

> db.dowonDB.group( { key: {'dept_id': true},   reduce: function(obj, prev) { prev.sum += obj.salary },   initial: {sum: 0}, condition: {'dept_id': {$gt:2}  } });
[ { "dept_id" : 3, "sum" : 5 } ]

> db.dowonDB.group( { key: {'dept_id': true},   reduce: function(obj, prev) { prev.sum += obj.salary },   initial: {sum: 0}, condition: {'dept_id': {$gte:2}  } });
[ { "dept_id" : 2, "sum" : 38 }, { "dept_id" : 3, "sum" : 5 } ]

또는

> db.dowonDB.group( { key: {'dept_id': true},   reduce: function(obj, prev) { prev.sum += obj.salary; prev.cnt++ },   initial: {sum: 0, avg:0, cnt:0}, condition: {'dept_id': {$gte:2}  }, finalize: function(out){ out.avg = out.sum/out.cnt;}  });

[
{
"dept_id" : 2,
"sum" : 38,
"avg" : 12.666666666666666,
"cnt" : 3
},
{
"dept_id" : 3,
"sum" : 5,
"avg" : 2.5,
"cnt" : 2
}
]



5. 심화학습 

  - 동영상 강좌를 보자 

    


  - 상단의 Group만들기에서 map, reduce의 흐름도 

  - Sql처럼 sub query를 하지 않고 Reduce Function을 사용하여 코딩하면 된다

  - Framework Flow PDF : collectoin에 대해서 mapping 후 reducing 하여 result 결과를 만들어 낸다 

  - 데이터 Collection에서 key에 맞는 Map을 만들고, 비즈니스 로직에 맞게 Reduce 펑션을 만든 결과를 

    실시간으로 서비스한다

  - Intermediate-1 = unwind = map = key:value로 만들기

    Intemediate-2 = group = reduce



  - 이제 group으로 작업하지 말고 Pipeline Operation으로 하는 aggregate를 사용한다. 또는 mapreduce를 사용한다 

  - 결국 v2.2 에 오면 mapreduce를 사용한다 : 비즈니스적으론 BI 솔루션과 맵핑하여 UX로 표현한다 (Real-Time)

  - SNS에서 오는 실시간 데이터가 쌓여서 BigData가 되고 이를 저장하고 처리하는 것이 MongoDB로 웹앱기술과 찰떡 궁합!

  - 해당 작업은 disk가 아니라 memory cache해서 사용한다 (메뉴얼상으로)

 /////////////////////////////////////

// 형식 

> db.dowonDB.mapreduce(map, reduce, out)


// mongo에서 map 

> var map = function() { for(var key in this) {   emit(key,{count: 1}) } }

> var reduce = function(emits){ total=0; for(var i in emits) { total+=emits[i].count; } return {'count': total}; }

> var mr = db.runCommand({'mapreduce':'dowonDB', 'map':map, 'reduce':reduce, 'out':{'inline':1}});

// 결과 

> mr

{

"results" : [

{

"_id" : "_id",

"value" : {

"count" : NaN

}

},

{

"_id" : "a",

"value" : {

"count" : NaN

}

},

{

"_id" : "dept_id",

"value" : {

"count" : NaN

}

},

{

"_id" : "salary",

"value" : {

"count" : NaN

}

}

],

"timeMillis" : 14,

"counts" : {

"input" : 12,

"emit" : 32,

"reduce" : 4,

"output" : 4

},

"ok" : 1

}


또는 


//////////////////////////////////////////////////////////

// dowonDB2 컬렉션으로 새롭게 tags 컬럼 넣기 

> db.dowonDB2.save({_id: 1, tags:['dog', 'cat']})

> db.dowonDB2.save({_id: 2, tags:['cat']})

> db.dowonDB2.save({_id: 3, tags:['mouse', 'cat', 'dog']})

> db.dowonDB4.save({_id: 4, tags:[]})


// map과 reduce를 만듦 

> var map2 = function() { this.tags.forEach( function(z) { emit(z, {count: 1}); } ); }

> var reduce2 = function(key, values) { var total=0; for(var i=0; i < values.length; i++) { total += values[i].count; } return {count:total}; }


// mapReduce 호출

> var mr2 = db.dowonDB2.mapReduce( map2, reduce2, {out:{inline:1}} );

> mr2

{

"results" : [

{

"_id" : "cat",

"value" : {

"count" : 3

}

},

{

"_id" : "dog",

"value" : {

"count" : 2

}

},

{

"_id" : "mouse",

"value" : {

"count" : 1

}

}

],

"timeMillis" : 3,

"counts" : {

"input" : 3,

"emit" : 6,

"reduce" : 2,

"output" : 3

},

"ok" : 1,

}


  - MongoDB API 

db.runCommand(

    {

     mapReduce: <collection>,

     map: <function>,

     reduce: <function>,

     out: <output>,

     query: <document>,

     sort: <document>,

     limit: <number>,

     finalize: <function>,

     scope: <document>,

     jsMode: <boolean>,

     verbose: <boolean>

    }

)


  - MapReduce의 최종 목적은 무얼까?  SPA방식의 Web Application 서비스의 구현을 위한 것은 아닐까?

    10Gen에서 이야기하는 MongoDB in SPA (이용 : Node.js + Express.js + Mongoose.js + MongoDB)

   



<참조>

  - MongoDB Aggregation Framework Concept

  - MongoDB Aggragation Framework Examples

  - Collection Functions 목록

  - Aggregation Framework의 Pipeline 과 Expression 예제

  - count, distinct, group 예제

  - DataBase Projection 개념

'MongoDB > MapReduce' 카테고리의 다른 글

[MongoDB] Aggregation Framework 실습하기  (0) 2013.08.03
[MongoDB] GridFS 사용하기  (0) 2013.02.23
[MongoDB] GridFS 개념잡기  (0) 2013.02.23
posted by 윤영식
2013. 2. 23. 16:53 MongoDB/MapReduce

GridFS에 대하여 샘플을 돌려보자


1) 예제 다운로드 

  - git 복제한다

[~/development/mongodb]git clone https://github.com/jamescarr/nodejs-mongodb-streaming.git gridfs_mongoose

Cloning into 'gridfs_mongoose'...

remote: Counting objects: 44, done.

remote: Compressing objects: 100% (30/30), done.

remote: Total 44 (delta 12), reused 40 (delta 8)

Unpacking objects: 100% (44/44), done.


  - 파일을 JetBrains WebStorm에서 열어보았다 

    + coffee-script 이용하여 app.js 를 app.coffee 로 작성

  


  - 실행하기전 express, mongoose, request, jade 모듈 설치

    + npm install express

    + npm install mongoose

    + npm install request


  - 실행 : http://localhost:3000 호출

    + 호출하기전 MongoDB를 start 해 놓아야 한다 

[~/development/mongodb/gridfs_mongoose]coffee app

Server running. Navigate to localhost:3000

  

    + 브라우져 호출하면 파일 업로드 화면이 나온다

  

 


2) GridFS 파일 업로드 하기 

  - 화면에서 Name을 입력하고 File 을 선택한 후 "제출" 버튼을 클릭한다 


  - MongoDB의 mongo에서 확인을 한다 : dowonFile 은 프로그램안에서 사용한 Collection 명칭이다

[~/mongodb]mongo

MongoDB shell version: 2.2.3

connecting to: test


///////////////

//  제출전 상태

> show dbs

local (empty)


///////////////

//  제출후 상태

> show dbs

dowonFile 0.203125GB

local (empty)

> use dowonFile

switched to db dowonFile

> show collections

applications

fs.chunks

fs.files

system.indexes

> db.applications.find();

{ "name" : "dowonGridFileSample", "_id" : ObjectId("51392f28dfa5f69404000001"), "files" : [ { "md5" : "6dda9a5cd37e113b246fd00604bf3638", "uploadDate" : ISODate("2013-03-08T00:22:01.077Z"), "chunkSize" : 262144, "length" : 7772701, "contentType" : "binary/octet-stream", "_id" : ObjectId("51392f28dfa5f69404000002") } ] }



3) 예제 분석하기 

  - *.coffee 를 컴파일하여 분석할 수도 있다 : coffee -c *.coffee 수행하면 *.js 파일 생성됨

  - 가급적 coffee-script에 익숙해 지도록 하자 (참조)

  - app.coffee 

    + 기본 환경 셋업

    + 스키마 생성

    + 호출을 위한 get/post 구성 : /new/:id 값을 RESTful 로 호출하면 파일을 다운로드 받을 수 있다 (id는 몽고디비에서 _id 참조)

  

  - gridfs.coffee

    + gridfs 전용 put, find 관련 메소드를 정의하여 모듈화 한다 


4) Mocha 테스트 

  - git clone 받은 디렉토리에서 Mocha 테스트를 수행한다 : current 디렉토리 밑으로 test 디렉토리의 테스트 파일을 자동 수행한다

  - 테스트 파일 형식

    + .js : mocha

    + .coffee : mocha --compilers coffee:coffee-script



<참조>

  - 원문 : nodejs-mongodb-streaming (Node.js mongoose+GridFS 예제)


'MongoDB > MapReduce' 카테고리의 다른 글

[MongoDB] Aggregation Framework 실습하기  (0) 2013.08.03
[MongoDB] Aggregation Framework 이해하기  (0) 2013.08.03
[MongoDB] GridFS 개념잡기  (0) 2013.02.23
posted by 윤영식
2013. 2. 23. 15:50 MongoDB/MapReduce

몽고디비가 샤딩으로 저장한 데이터들은 어떻게 조회되어 가져올 수 있을까? GridFS에 대해서 알아보자. 텐젠의 설명을 잠시 보자

GridFS is a specification for storing and retrieving files that exceed the BSON-document size limit of 16MB.

(GridFS는 16MB 넘는 사이즈의 데이터를 저장하고 조회하는 명세이다. 모든 파일을 도큐먼트로 다룬다는게 중요하겠다)


Instead of storing a file in an single document, GridFS divides a file into parts, or chunks, [1] and stores each of those chunks as a separate document. By default GridFS limits chunk size to 256k. GridFS uses two collections to store files. One collection stores the file chunks, and the other stores file metadata.

(한개의 파일로 저장하는 대신에 부분이나 청크로 나누어 분리된 도큐먼트를 청크로 저장한다. 청크사이즈는 기본 256k로 제한되어 있다. 파일 청크와 메타데이터를 저장하는 두개의 컬렉션을 사용한다)



1) 개념

  - 분산 파일 시스템 : Redis (Map-key:value- Data)

  - Redis와 같은 기능을 MongoDB에서는 GridFS에서 담당한다

  - mongoose ODM 드라이버를 통해서 GridFS를 사용할 수 있다


2) 사용하기 

  - javascript.pdf 50.3MBytes 자리 파일을 GridFS로 구성

  - 미디어 파일도 MongoDB에 컬렉션으로 관리하게 되는 것이다 

[~/mongodb]mongofiles -d dowon put javascript.pdf

connected to: 127.0.0.1

added file: { _id: ObjectId('5128625889a440df3f1359db'), filename: "javascript.pdf", chunkSize: 262144, uploadDate: new Date(1361601113683), md5: "57b836baabd09c486778e192fa6c350e", length: 53872431 }

done!


///////////////

// 결과 

[~/mongodb]mongo

MongoDB shell version: 2.2.3

connecting to: test

> show dbs

dowon 0.203125GB

dowonDB 0.203125GB

local (empty)

> use dowon

switched to db dowon

> show collections

fs.chunks

fs.files

system.indexes

> db.fs.files.find();

{ "_id" : ObjectId("5128625889a440df3f1359db"), "filename" : "javascript.pdf", "chunkSize" : 262144, "uploadDate" : ISODate("2013-02-23T06:31:53.683Z"), "md5" : "57b836baabd09c486778e192fa6c350e", "length" : 53872431 }


  - 대용량 데이터를 그림처럼 GridFS로 저장하면

    + 맵 : 분산된 데이터를 Key=Value (map) 기반으로 찾고

    + 리듀스 : 자바스크립트 펑션을 통하여 통합한다(비즈니스 로직 구현)

  



<참조>

  - 몽구스(mongoose)를 이용하여 gridfs 구현하기 

  - 텐젠 메뉴얼 : http://docs.mongodb.org/manual/applications/gridfs/


'MongoDB > MapReduce' 카테고리의 다른 글

[MongoDB] Aggregation Framework 실습하기  (0) 2013.08.03
[MongoDB] Aggregation Framework 이해하기  (0) 2013.08.03
[MongoDB] GridFS 사용하기  (0) 2013.02.23
posted by 윤영식
prev 1 next