수색…
소개
Aggregations
연산은 데이터 레코드를 처리하고 계산 된 결과를 반환합니다. 집계 연산은 여러 문서의 값을 함께 그룹화하고 그룹화 된 데이터에서 다양한 작업을 수행하여 단일 결과를 반환 할 수 있습니다. MongoDB는 집계를 수행하는 세 가지 방법 인 집계 파이프 라인, map-reduce 함수 및 단일 목적 집계 메소드를 제공합니다.
Mongo 매뉴얼 ( https://docs.mongodb.com/manual/aggregation/)
통사론
- db.collection.aggregate (파이프 라인, 옵션)
매개 변수
매개 변수 | 세부 |
---|---|
관로 | 배열 (데이터 집계 연산 또는 스테이지 시퀀스) |
옵션들 | 문서 (선택 사항, 파이프 라인이 배열로 존재하는 경우에만 사용 가능) |
비고
MongoDB의 집계 프레임 워크는 SQL의 일반적인 GROUP BY
기능을 구현하는 데 사용됩니다.
모든 예제에서 이름이 지정된 transactions
콜렉션에서 다음 삽입을 고려하십시오.
> db.transactions.insert({ cr_dr : "D", amount : 100, fee : 2});
> db.transactions.insert({ cr_dr : "C", amount : 100, fee : 2});
> db.transactions.insert({ cr_dr : "C", amount : 10, fee : 2});
> db.transactions.insert({ cr_dr : "D", amount : 100, fee : 4});
> db.transactions.insert({ cr_dr : "D", amount : 10, fee : 2});
> db.transactions.insert({ cr_dr : "C", amount : 10, fee : 4});
> db.transactions.insert({ cr_dr : "D", amount : 100, fee : 2});
카운트
차변 및 신용 거래 수는 어떻게 계산합니까? 한 가지 방법은 count()
함수를 사용하는 것입니다.
> db.transactions.count({cr_dr : "D"});
또는
> db.transactions.find({cr_dr : "D"}).length();
cr_dr
upfront의 가능한 값을 모른다면 어떻게 cr_dr
? 여기에서 Aggregation 프레임 워크가 제공됩니다. 아래의 집계 쿼리를 참조하십시오.
> db.transactions.aggregate(
[
{
$group : {
_id : '$cr_dr', // group by type of transaction
// Add 1 for each document to the count for this type of transaction
count : {$sum : 1}
}
}
]
);
결과는 다음과 같습니다.
{
"_id" : "C",
"count" : 3
}
{
"_id" : "D",
"count" : 5
}
합집합
amount
의 합계를 얻는 방법? 아래의 집계 쿼리를 참조하십시오.
> db.transactions.aggregate(
[
{
$group : {
_id : '$cr_dr',
count : {$sum : 1}, //counts the number
totalAmount : {$sum : '$amount'} //sums the amount
}
}
]
);
결과는 다음과 같습니다.
{
"_id" : "C",
"count" : 3.0,
"totalAmount" : 120.0
}
{
"_id" : "D",
"count" : 5.0,
"totalAmount" : 410.0
}
amount
과 fee
를 합한 다른 버전.
> db.transactions.aggregate(
[
{
$group : {
_id : '$cr_dr',
count : {$sum : 1},
totalAmount : {$sum : { $sum : ['$amount', '$fee']}}
}
}
]
);
결과는 다음과 같습니다.
{
"_id" : "C",
"count" : 3.0,
"totalAmount" : 128.0
}
{
"_id" : "D",
"count" : 5.0,
"totalAmount" : 422.0
}
평균
차변 및 신용 거래의 평균 금액을 얻는 방법?
> db.transactions.aggregate(
[
{
$group : {
_id : '$cr_dr', // group by type of transaction (debit or credit)
count : {$sum : 1}, // number of transaction for each type
totalAmount : {$sum : { $sum : ['$amount', '$fee']}}, // sum
averageAmount : {$avg : { $sum : ['$amount', '$fee']}} // average
}
}
]
)
결과는 다음과 같습니다.
{
"_id" : "C", // Amounts for credit transactions
"count" : 3.0,
"totalAmount" : 128.0,
"averageAmount" : 40.0
}
{
"_id" : "D", // Amounts for debit transactions
"count" : 5.0,
"totalAmount" : 422.0,
"averageAmount" : 82.0
}
배열 작업.
배열의 데이터 항목을 사용하여 작업하려면 먼저 배열을 풀어야 합니다. unwind 작업은 배열의 각 항목에 대한 문서를 만듭니다. 큰 배열이있는 문서가 많으면 문서 수가 폭발적으로 늘어납니다.
{ "_id" : 1, "item" : "myItem1", sizes: [ "S", "M", "L"] }
{ "_id" : 2, "item" : "myItem2", sizes: [ "XS", "M", "XL"] }
db.inventory.aggregate( [ { $unwind : "$sizes" }] )
중요한주의 사항은 문서에 배열이 포함되어 있지 않으면 잃어 버리게된다는 것입니다. mongo 3.2 이상에서는 unwind 옵션 "preserveNullAndEmptyArrays"가 추가되었습니다. 이 옵션은 배열이 없을 때 문서가 보존되도록합니다.
{ "_id" : 1, "item" : "myItem1", sizes: [ "S", "M", "L"] }
{ "_id" : 2, "item" : "myItem2", sizes: [ "XS", "M", "XL"] }
{ "_id" : 3, "item" : "myItem3" }
db.inventory.aggregate( [ { $unwind : { path: "$sizes", includeArrayIndex: "arrayIndex" } }] )
시합
전체 직원의 평균 연령이 $ 70000 이하인 모든 부서를 얻기 위해 쿼리를 작성하는 방법이 35보다 크거나 같습니까?
이를 위해 우리는 $ 70000 이하의 급여를 가진 직원과 일치하는 쿼리를 작성할 필요가 있습니다. 그런 다음 집계 단계를 추가하여 부서별 직원을 그룹화합니다. eg average_age라는 필드가있는 누적기를 추가하여 $ avg 누적기를 사용하여 부서 당 평균 연령을 찾은 다음 기존의 $ match 및 $ group aggregates 아래에 다른 $ match aggregate를 추가하여 average_age가 average 인 결과 만 검색합니다 35보다 크거나 같은
db.employees.aggregate([
{"$match": {"salary": {"$lte": 70000}}},
{"$group": {"_id": "$dept",
"average_age": {"$avg": "$age"}
}
},
{"$match": {"average_age": {"$gte": 35}}}
])
결과는 다음과 같습니다.
{
"_id": "IT",
"average_age": 31
}
{
"_id": "Customer Service",
"average_age": 34.5
}
{
"_id": "Finance",
"average_age": 32.5
}
컬렉션에서 중복 입력란이있는 문서 삭제 (중복 제거)
allowDiskUse : true 옵션은 선택 사항이지만 컬렉션 크기가 클 경우이 집계가 메모리 집약적 인 작업이 될 수 있으므로 메모리 문제를 줄일 수 있으므로 항상 사용하는 것이 좋습니다.
var duplicates = [];
db.transactions.aggregate([
{ $group: {
_id: { cr_dr: "$cr_dr"},
dups: { "$addToSet": "$_id" },
count: { "$sum": 1 }
}
},
{ $match: {
count: { "$gt": 1 }
}}
],allowDiskUse: true}
)
.result
.forEach(function(doc) {
doc.dups.shift();
doc.dups.forEach( function(dupId){
duplicates.push(dupId);
}
)
})
// printjson(duplicates);
// Remove all duplicates in one go
db.transactions.remove({_id:{$in:duplicates}})