본문 바로가기
  • 문과생의 백엔드 개발자 성장기
|Playdata_study/mongoDB

210614_mongoDB3

by 케리's 2021. 6. 14.

Q1) Product 전체 내용을 출력해보자. _id는 빼고출력하자.


 db.Product.find({},{_id:0});

 

> db.Product.find({},{_id:0});
{ "Name" : "notebook", "Price" : 200, "Category" : "material" }
{ "Name" : "pencil", "Price" : 80, "Category" : "material" }
{ "Name" : "salad", "Price" : 220, "Category" : "food" }
{ "Name" : "others", "Price" : 20, "Category" : "material" }
{ "Name" : "bread", "Price" : 100, "Category" : "food" }
>

 

 

 


Q2) ID와 가격을 출력해보자.

 

 : aggregate 는 pipeline을 가지면서 각 단계별로 진행을 마친 후 result 를 반환한다. 

  순서 → collection > $project > $match > $group > $sort > $skip > $limit > $unwind > $out

 : $project : find와 같다

 

 

(1)

db.Product.aggregate([{
                              $project:{_id:1,Price:1}
                              }]);

 

> db.Product.aggregate([{$project:{_id:1,Price:1}}]);

{ "_id" : ObjectId("60c3064598e69dd9d8688089"), "Price" : 200 }
{ "_id" : ObjectId("60c3064598e69dd9d868808a"), "Price" : 80 }
{ "_id" : ObjectId("60c3064598e69dd9d868808b"), "Price" : 220 }
{ "_id" : ObjectId("60c3064598e69dd9d868808c"), "Price" : 20 }
{ "_id" : ObjectId("60c3064698e69dd9d868808d"), "Price" : 100 }
>

 

(2)
db.Product.aggregate([{
                             $project:{Price:1}
                             }]);

 

 

> db.Product.aggregate([{$project:{Price:1}}]);

{ "_id" : ObjectId("60c3064598e69dd9d8688089"), "Price" : 200 }
{ "_id" : ObjectId("60c3064598e69dd9d868808a"), "Price" : 80 }
{ "_id" : ObjectId("60c3064598e69dd9d868808b"), "Price" : 220 }
{ "_id" : ObjectId("60c3064598e69dd9d868808c"), "Price" : 20 }
{ "_id" : ObjectId("60c3064698e69dd9d868808d"), "Price" : 100 }
>


db.Product.aggregate([{
                             $project:{_id:0, Price:1}
                             }]);

 

> db.Product.aggregate([{$project:{_id:0, Price:1}}]);
{ "Price" : 200 }
{ "Price" : 80 }
{ "Price" : 220 }
{ "Price" : 20 }
{ "Price" : 100 }

 

 

 


Q3) 이름과 가격만 출력하자.

 

db.Product.aggregate([{
                            $project:{Name:1,Price:1,_id:0}
                            }]);

 

> db.Product.aggregate([{$project:{Name:1, Price:1,_id:0}}]);

{ "Name" : "notebook", "Price" : 200 }
{ "Name" : "pencil", "Price" : 80 }
{ "Name" : "salad", "Price" : 220 }
{ "Name" : "others", "Price" : 20 }
{ "Name" : "bread", "Price" : 100 }

 

 

 


Q4) 가격과 카테고리만 출력하자. 단 가격별 오름차순으로 정렬해보자.
     $sort: 1 은 유/무가 아닌 오름차 순 정렬

db.Product.aggregate([
                            {$project:{Name:1,Price:1,_id:0}},
                            {$sort:{Price:1}}
                            ]);

 

> db.Product.aggregate([{$project:{Name:1, Price:1, _id:0}},{$sort:{Price:1}}]);

{ "Name" : "others", "Price" : 20 }
{ "Name" : "pencil", "Price" : 80 }
{ "Name" : "bread", "Price" : 100 }
{ "Name" : "notebook", "Price" : 200 }
{ "Name" : "salad", "Price" : 220 }
>

 

 

 


Q5) 이름(목록)과 가격만 출력하되 목록을 내림차 순으로 정렬해보자.

db.Product.aggregate([
                            {$project:{Name:1,Price:1,_id:0}},
                            {$sort:{Name:-1}}
                             ]);

 

> db.Product.aggregate([{$project:{Name:1, Price:1, _id:0}},{$sort:{Price:-1}}]);

{ "Name" : "salad", "Price" : 220 }
{ "Name" : "notebook", "Price" : 200 }
{ "Name" : "bread", "Price" : 100 }
{ "Name" : "pencil", "Price" : 80 }
{ "Name" : "others", "Price" : 20 }

 

 

 



Q6) $project로 가서 별칭을 주는것을 확인 한 후 아래와 같이 이름(목록)만 출력해보자.

    : $ 를 주면 별칭이 된다.


db.Product.aggregate([
                            {$project: {_id:0, alias_name : "$Name" }}
                            ]);

> db.Product.aggregate([{$project:{_id:0, alias_name:"$Name"}}]);

{ "alias_name" : "notebook" }
{ "alias_name" : "pencil" }
{ "alias_name" : "salad" }
{ "alias_name" : "others" }
{ "alias_name" : "bread" }
>

 

 

 

 


Q7) Name을 목록, Price 가격, Category는 타입으로 별칭을 주자.


db.Product.aggregate([
                            {$project: {_id:0, 목록:"$Name", 가격:"$Price", 타입 : "$Category" }}
                            ]);

 

> db.Product.aggregate([{$project:{_id:0, 목록:"$Name", 가격:"$Price", 타입:"$Category"}}]);

{ "목록" : "notebook", "가격" : 200, "타입" : "material" }
{ "목록" : "pencil", "가격" : 80, "타입" : "material" }
{ "목록" : "salad", "가격" : 220, "타입" : "food" }
{ "목록" : "others", "가격" : 20, "타입" : "material" }
{ "목록" : "bread", "가격" : 100, "타입" : "food" }

 

 

 

 


Q8) 상품의 목록을 출력하고 inc_price라는 별칭을 주고 가격에 100을 더한 값을 출력해보자.

    :   total(별칭): { $add: [ "$price(1)", "$fee(2)" ] } = (1) + (2) 값 출력


db.Product.aggregate([
                            {$project: {_id:0, Name:1,
                            inc_price: {$add:["$Price", 100 ]}}}]);

 

> db.Product.aggregate([{$project:{_id:0, Name:1, inc_price:{$add:["$Price",100]}}}]);

{ "Name" : "notebook", "inc_price" : 300 }
{ "Name" : "pencil", "inc_price" : 180 }
{ "Name" : "salad", "inc_price" : 320 }
{ "Name" : "others", "inc_price" : 120 }
{ "Name" : "bread", "inc_price" : 200 }
>

 

 

 

 


Q9) $max, $group
     카테고리로 그룹화를 한다음 최대 가격을 출력해보자.
   : _id가 고유 값 이기 때문에, _id를 기준으로 입력 문서를 그룹화 한 후, 개별 그룹에 대해 문서를 출력한다.


db.Product.aggregate([
                            {$group: {_id:"$Category", max_price : {$max: "$Price" }}}
                             ]);

> db.Product.aggregate([{$group:{_id:"$Category", max_price:{$max:"$Price"}}}]);

{ "_id" : "material", "max_price" : 200 }
{ "_id" : "food", "max_price" : 220 }

 

 

 

 


Q10) $min, $group
       카테고리로 그룹화를 한다음 최소 가격을 출력해보자.

 

db.Product.aggregate([
                            {$group: {_id:"$Category", min_price : {$min: "$Price" }}}
                             ]);

 

> db.Product.aggregate([{$group:{_id:"$Category", min_price:{$min:"$Price"}}}]);

{ "_id" : "material", "min_price" : 20 }
{ "_id" : "food", "min_price" : 100 }
>

 

 

 

 


Q11) 상품목록을 출력하고 가격의 합과 가격의 평균 및 목록의 갯수를 구한다.

  : $sum 은 갯수를 count 하거나 value 를 더해준다.

 


db.Product.aggregate([
                             $group: {_id:"$Category", sum :{$sum: "$Price"},
                             avg:{$avg:"$Price"},
                             count:{$sum:1}}}
                             ]);

 

> db.Product.aggregate([{$group:{_id:"$Category", sum:{$sum:"$Price"}, 
                         avg:{$avg:"$Price"}, count:{$sum:1}}}]);
                         
{ "_id" : "material", "sum" : 300, "avg" : 100, "count" : 3 }
{ "_id" : "food", "sum" : 320, "avg" : 160, "count" : 2 }

 

 

 

 


Q12) 상품 목록을 출력하고 그룹화 한 다음 갯수를 구해보자.

 

(1)
db.Product.aggregate([
                            {$group: {_id:"$Category", count:{$sum:1}}}
                             ]);

 

> db.Product.aggregate([{$group:{_id:"$Category", count:{$sum:1}}}]);

{ "_id" : "material", "count" : 3 }
{ "_id" : "food", "count" : 2 }
>

 


(2) 

  :  $literal : 구문 분석하지 않고 값을 반환 , 즉 그대로 이름이 지정된 필드 값 반환 

    $literal : $1 은 $1 그대로 반환한다.

 


db.Product.aggregate([
{$project: {"Category":1, count:{$literal:1}}},
{$group : {_id: "$Category" , count:{$sum:"$count"}}}
]);

 

> db.Product.aggregate([{$project:{"Category":1, count:{$literal:1}}}, // conut = 1
                       {$group:{_id:"$Category", count:{$sum:"$count"}}}]);
                       
{ "_id" : "material", "count" : 3 }
{ "_id" : "food", "count" : 2 }

 

 

 

 


Q13) Name에서 bread를 찾아서 출력하자.

 : $match : 문서를 필터링하여 지정된 조건과 일치하는 문서만 다음 파이프 라인 단계로 전달

 


db.Product.aggregate([
                            {$project:{_id:0, Name:1}}, {$match:{Name:"bread"}}
                             ]);

 

> db.Product.aggregate([{$project:{_id:0, Name:1}},{$match:{Name:"bread"}}]);

{ "Name" : "bread" }
>

 

 

 


Q14) Category에서 food만 출력해보자.


db.Product.aggregate([
                             {$match:{Category:"food"}}
                              ]);

 

 

> db.Product.aggregate([{$match:{Category:"food"}}]);
{ "_id" : ObjectId("60c3064598e69dd9d868808b"), "Name" : "salad", "Price" : 220, "Category" : "food" }
{ "_id" : ObjectId("60c3064698e69dd9d868808d"), "Name" : "bread", "Price" : 100, "Category" : "food" }
>

 

> db.Product.aggregate([{$project:{_id:0}},{$match:{Category:"food"}}]);
{ "Name" : "salad", "Price" : 220, "Category" : "food" }
{ "Name" : "bread", "Price" : 100, "Category" : "food" }
>

 


 Q15) Category에서 food 가격의 최대, 최소, , 평균 갯수를 출력해보자.

 


db.Product.aggregate([
                             {$match:{Category:"food"}},
                             {$group: {_id:"$Category",
                                         max:{$max:"$Price"},
                                         min:{$min:"$Price"},
                                         sum :{$sum: "$Price"},
                                         avg:{$avg:"$Price"},
                                         count:{$sum:1}}}

                               ]);

 

> db.Product.aggregate([
...                              {$match:{Category:"food"}},
...                              {$group: {_id:"$Category",
...                                          max:{$max:"$Price"},
...                                          min:{$min:"$Price"},
...                                          sum :{$sum: "$Price"},
...                                          avg:{$avg:"$Price"},
...                                          count:{$sum:1}}}
...
...                                ]);
{ "_id" : "food", "max" : 220, "min" : 100, "sum" : 320, "avg" : 160, "count" : 2 }
>

 


db.Product.aggregate([
             {$group : {_id:"$Category",
                  max : {$max:"$Price"},
                  min : {$min:"$Price"},
                  sum : {$sum: "$Price"},
                  avg : {$avg:"$Price"},
                  count : {$sum:1}}},
                 {$match:{_id:"food"}}
                 ]);

 

> db.Product.aggregate([
...              {$group : {_id:"$Category",
...                   max : {$max:"$Price"},
...                   min : {$min:"$Price"},
...                   sum : {$sum: "$Price"},
...                   avg : {$avg:"$Price"},
...                   count : {$sum:1}}},
...                  {$match:{_id:"food"}}
...                  ]);
{ "_id" : "food", "max" : 220, "min" : 100, "sum" : 320, "avg" : 160, "count" : 2 }

 

 

 

 


Q16) 15번을 맵리듀스로 작성 해보자.

 

 

function map(){
             emit (this.Category,{sum:this.Price, min:this.Price, max:this.Price, count:1});
                  }

 


function reduce(key, values){
                 var result = {Category : key, sum:0, min:10000, max:0, count:0}
                 values.forEach(function(v){
                 result.count += v.count;
                 result.sum += v.sum;
                 result.min = Math.min(v.min, result.min);
                 result.max = Math.max(v.max, result.max);
                 });
return result;
}

 

 

db.Product.mapReduce(map, reduce, {out:{replace : "myResult02"}});
db.myResult02.find();

 

> function map(){
...              emit (this.Category,{sum:this.Price, min:this.Price, max:this.Price, count:1});
...                   }
> function reduce(key, values){
...                  var result = {Category : key, sum:0, min:10000, max:0, count:0}
...                  values.forEach(function(v){
...                  result.count += v.count;
...                  result.sum += v.sum;
...                  result.min = Math.min(v.min, result.min);
...                  result.max = Math.max(v.max, result.max);
...                  });
... return result;
... }
> db.Product.mapReduce(map, reduce, {out:{replace : "myResult02"}});
{ "result" : "myResult02", "ok" : 1 }

> db.myResult02.find();
{ "_id" : "material", "value" : { "Category" : "material", "sum" : 300, "min" : 20, "max" : 200, "count" : 3 } }
{ "_id" : "food", "value" : { "Category" : "food", "sum" : 320, "min" : 100, "max" : 220, "count" : 2 } }
>

 

 

 

 Indexes

 : 특정 필드 또는 필드 세트값에 따라 정렬하여 저장, 인덱스의 순서를 사용하여 정렬된 결과 반환

 

 

db.Product.getIndexes();
db.Product.aggregate([ {$project:{_id:0, Name:1}}, {$match: {Name:"bread"}}]);
db.Product.getIndexes();

 

> db.Product.getIndexes();
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" } ]
> db.Product.aggregate([{$project:{_id:0, Name:1}}, {$match:{Name:"bread"}}]);
{ "Name" : "bread" }
> db.Product.getIndexes();
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" } ]
>

 


1) 인덱스를 추가설정


db.Product.ensureIndex ({Name : 1});

 

> db.Product.ensureIndex({Name:1});
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}
>

 


2) 추가된 인덱스 필드의 값을 찾아서 실행 결과를 확인

 

db.Product.find({Name:"bread"}).explain();

 

> db.Product.find({Name:"bread"}).explain();
{
        "queryPlanner" : {
                "plannerVersion" : 1,
                "namespace" : "my_score.Product",
                "indexFilterSet" : false,
                "parsedQuery" : {
                        "Name" : {
                                "$eq" : "bread"
                        }
                },
                "queryHash" : "EBFEE4C5",
                "planCacheKey" : "6D446D9E",
                "winningPlan" : {
                        "stage" : "FETCH",
                        "inputStage" : {
                                "stage" : "IXSCAN",
                                "keyPattern" : {
                                        "Name" : 1
                                },
                                "indexName" : "Name_1",
                                "isMultiKey" : false,
                                "multiKeyPaths" : {
                                        "Name" : [ ]
                                },
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 2,
                                "direction" : "forward",
                                "indexBounds" : {
                                        "Name" : [
                                                "[\"bread\", \"bread\"]"
                                        ]
                                }
                        }
                },
                "rejectedPlans" : [ ]
        },
        "serverInfo" : {
                "host" : "hyeripark",
                "port" : 27017,
                "version" : "4.4.6",
                "gitVersion" : "72e66213c2c3eab37d9358d5e78ad7f5c1d0d0d7"
        },
        "ok" : 1
}
>

 


3) 인덱스 삭제


db.Product.dropIndex ({Name : 1});
db.Product.getIndexes();

 

> db.Product.dropIndex({Name:1});
{ "nIndexesWas" : 2, "ok" : 1 }
> db.Product.getIndexes();
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" } ]

 


4)  이름 순으로 정렬


db.Product.find().sort({Name : 1});

 

> db.Product.find().sort({Name:1});
{ "_id" : ObjectId("60c3064698e69dd9d868808d"), "Name" : "bread", "Price" : 100, "Category" : "food" }
{ "_id" : ObjectId("60c3064598e69dd9d8688089"), "Name" : "notebook", "Price" : 200, "Category" : "material" }
{ "_id" : ObjectId("60c3064598e69dd9d868808c"), "Name" : "others", "Price" : 20, "Category" : "material" }
{ "_id" : ObjectId("60c3064598e69dd9d868808a"), "Name" : "pencil", "Price" : 80, "Category" : "material" }
{ "_id" : ObjectId("60c3064598e69dd9d868808b"), "Name" : "salad", "Price" : 220, "Category" : "food" }

 


5) bread 찾아서 실행 결과를 확인


db.Product.find({Name:"bread"}).explain();

 

> db.Product.find({Name:"bread"}).explain();
{
        "queryPlanner" : {
                "plannerVersion" : 1,
                "namespace" : "my_score.Product",
                "indexFilterSet" : false,
                "parsedQuery" : {
                        "Name" : {
                                "$eq" : "bread"
                        }
                },
                "queryHash" : "EBFEE4C5",
                "planCacheKey" : "EBFEE4C5",
                "winningPlan" : {
                        "stage" : "COLLSCAN",
                        "filter" : {
                                "Name" : {
                                        "$eq" : "bread"
                                }
                        },
                        "direction" : "forward"
                },
                "rejectedPlans" : [ ]
        },
        "serverInfo" : {
                "host" : "hyeripark",
                "port" : 27017,
                "version" : "4.4.6",
                "gitVersion" : "72e66213c2c3eab37d9358d5e78ad7f5c1d0d0d7"
        },
        "ok" : 1
}
>




MongoDB 지리 인덱스 쿼리 구성

 

 

 


✔ 지리공간 데이터를 저장하는 방법

 

 

  1. 좌표 : 종래의 좌표를 나타내는 데이터, 주로 평면상의 점을 사용, 표현할 수 있는 도형의 점
             {loc :[10,20]} 점만 사용

   2. GeoJSON : 새로운 다양한 형태를 표현할 수 있는 데이터, 주로 지구 표면에 위도, 경도를 다루는데 사용된다.
             {loc : {type : "Point", coordinates:[10,20]}}

 

 

 

 

 

✔ 쿼리 유형 세가지 : Geospatial Query Operators

 

 

   1. 내포된 쿼리 ($geoWithin) : 다각형 좌표, 사각좌표, 원형 좌표
                                          (지구 표면의 원형으로 검색된 쿼리 (2d/ 2dsphere) 모두 사용)
   2. 겹침 쿼리 ($geoIntersects) : (2dsphere 사용), , , 다각형
   3. 근거리 ($near) :  (2d/ 2dsphere) 사용,  점과의 거리, 좌표와 점과의 거리

 

 

 

 


✔ 검색조건 

 


1. GeoJSON : , $geometry : (type : "Point", coordinates: [ 40, 5 ])
   GeoJSON : 직선 $geometry : (type : "LineString",coordinates: [ [ 40, 5 ], [ 41, 6 ] ])
   GeoJSON : 다각형 $geometry : (type : "Polygon", coordinates: [ [ [ 0 , 0 ] , [ 3 , 6 ] , [ 6 , 1 ] , [ 0 , 0 ] ])
   GeoJSON : GeoJSON 집합 , $geometry:(type : "GeometryCollection", )

 


2.  좌표 : [x1, y1]
    좌표 : 사각형 $box : [[ <bottom left coordinates> ], [ <upper right coordinates> ]]
    좌표 : 다각형 , $polygon : [ [ <x1> , <y1> ], [ <x2> , <y2> ], [ <x3> , <y3> ], ... ]
    좌표 : 원형 , $center : [ [ <x>, <y> ] , <radius> ]
    좌표 : 지구 표면의 원형, $centerSphere : [ [ <x>, <y> ], <radius> ]

 

 

# Collection 생성 후 좌표 저장하자.


db.createCollection("location");
db.location.save({_id:"A", position : [0.001, -0.002]});
db.location.save({_id:"B", position : [1.0, 1.0]});
db.location.save({_id:"C", position : [0.5, 0.5]});
db.location.save({_id:"D", position : [-0.5, -0.5]});

 

> db.createCollection("location");
{ "ok" : 1 }

> db.location.save({_id:"A", position : [0.001, -0.002]});
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : "A" })
> db.location.save({_id:"B", position : [1.0, 1.0]});
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : "B" })
> db.location.save({_id:"C", position : [0.5, 0.5]});
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : "C" })
> db.location.save({_id:"D", position : [-0.5, -0.5]});
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : "D" })

> db.location.find()
{ "_id" : "A", "position" : [ 0.001, -0.002 ] }
{ "_id" : "B", "position" : [ 1, 1 ] }
{ "_id" : "C", "position" : [ 0.5, 0.5 ] }
{ "_id" : "D", "position" : [ -0.5, -0.5 ] }

 

 

2dinedex 

 : 2차원 평면에 점으로 저장된 데이터에 인덱스를 사용

 


db.location.ensureIndex({position:"2d"});
db.location.getIndexes();

 

 

> db.location.ensureIndex({position:"2d"});
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}
> db.location.getIndexes();
[
        {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_"
        },
        {
                "v" : 2,
                "key" : {
                        "position" : "2d"
                },
                "name" : "position_2d"
        }
]

 


# db.location.find({position : {$within:{$box: [[0.25,0.25],[1.0,1.0]]}}});

 

db.location.find({position : {$within:{$box: [[0.25,0.25],[1.0,1.0]]}}});
{ "_id" : "C", "position" : [ 0.5, 0.5 ] }
{ "_id" : "B", "position" : [ 1, 1 ] }

 

 

Q17) 현재 나의 위치가 0.0 주변의 약국을 동그라미로 찾았더니 A,B,C,D 위치가 리턴되더라.

       # $center : 크기제한없음


db.location.find({position : {$within:{$center:[[0,0],1.42]}}});

 

> db.location.find({position : {$within:{$center:[[0,0],1.42]}}});
{ "_id" : "D", "position" : [ -0.5, -0.5 ] }
{ "_id" : "A", "position" : [ 0.001, -0.002 ] }
{ "_id" : "C", "position" : [ 0.5, 0.5 ] }
{ "_id" : "B", "position" : [ 1, 1 ] }
>


Q18) 현재 나의 위치가 0.0에서 0.75 사이 거리의약국을 찾고싶다.

       # $maxDistance : 크기제한있음


db.location.find({position :{$near :[0,0], $maxDistance:0.75}});

 

> db.location.find({position :{$near :[0,0], $maxDistance:0.75}});
{ "_id" : "A", "position" : [ 0.001, -0.002 ] }
{ "_id" : "D", "position" : [ -0.5, -0.5 ] }
{ "_id" : "C", "position" : [ 0.5, 0.5 ] }
>

'|Playdata_study > mongoDB' 카테고리의 다른 글

210616_mongoDB5  (0) 2021.06.17
210615_mongoDB4  (0) 2021.06.15
210611_mongoDB2  (0) 2021.06.12
210610_mongoDB  (0) 2021.06.10

댓글