문서 메뉴

문서 홈애플리케이션 개발MongoDB 매뉴얼

$reduce (애그리게이션)

이 페이지의 내용

  • 정의
  • 예제
$reduce

버전 3.4에 새로 추가되었습니다.

배열의 각 요소에 표현식을 적용하고 이를 단일 값으로 결합합니다.

$reduce 의 구문은 다음과 같습니다:

{
$reduce: {
input: <array>,
initialValue: <expression>,
in: <expression>
}
}
필드
유형
설명
input
배열

배열로 해석되는 모든 유효한 표현식 일 수 있습니다. 표현식에 대한 자세한 내용은 표현식을 참조하세요 .

인수가 null 값으로 해석되거나 누락된 필드를 참조하는 경우 $reducenull 를 반환합니다.

인수가 배열 또는 null 로 해석되지 않거나 누락된 필드를 참조하는 경우 $reduce 는 오류를 반환합니다.

initialValue
표현식
in 이전에 설정된 초기 누적 valueinput 배열의 첫 번째 요소에 적용됩니다.
in
표현식

$reduceinput배열의 각 요소에 왼쪽에서 오른쪽 순서로 적용되는 유효한 표현식입니다. input 값에 $reverseArray 를 적용하여 결합 표현식을 오른쪽에서 왼쪽 순서로 적용한 결과와 동일하게 만듭니다.

in 표현식을 평가하는 동안 두 개의 변수를 사용할 수 있습니다.

  • value 은(는) 표현식의 누적값을 나타내는 변수입니다.

  • this 처리 중인 요소를 참조하는 변수입니다.

input 가 빈 배열로 해석되면 $reduceinitialValue 을 반환합니다.

예제
결과
{
$reduce: {
input: ["a", "b", "c"],
initialValue: "",
in: { $concat : ["$$value", "$$this"] }
}
}
"abc"
{
$reduce: {
input: [ 1, 2, 3, 4 ],
initialValue: { sum: 5, product: 2 },
in: {
sum: { $add : ["$$value.sum", "$$this"] },
product: { $multiply: [ "$$value.product", "$$this" ] }
}
}
}
{ "sum" : 15, "product" : 48 }
{
$reduce: {
input: [ [ 3, 4 ], [ 5, 6 ] ],
initialValue: [ 1, 2 ],
in: { $concatArrays : ["$$value", "$$this"] }
}
}
[ 1, 2, 3, 4, 5, 6 ]

events(이)라는 collection에는 확률 실험 이벤트가 포함됩니다. 각 실험에는 원하는 결과를 얻기 위해 주사위를 여러 번 굴리거나 카드를 여러 장 (교체 없이) 연속으로 뽑는 것과 같은 여러 events이(가) 있을 수 있습니다. 실험의 전체 확률을 구하려면 실험에서 각 이벤트의 확률을 곱해야 합니다.

db.events.insertMany( [
{ _id : 1, type : "die", experimentId :"r5", description : "Roll a 5", eventNum : 1, probability : 0.16666666666667 },
{ _id : 2, type : "card", experimentId :"d3rc", description : "Draw 3 red cards", eventNum : 1, probability : 0.5 },
{ _id : 3, type : "card", experimentId :"d3rc", description : "Draw 3 red cards", eventNum : 2, probability : 0.49019607843137 },
{ _id : 4, type : "card", experimentId :"d3rc", description : "Draw 3 red cards", eventNum : 3, probability : 0.48 },
{ _id : 5, type : "die", experimentId :"r16", description : "Roll a 1 then a 6", eventNum : 1, probability : 0.16666666666667 },
{ _id : 6, type : "die", experimentId :"r16", description : "Roll a 1 then a 6", eventNum : 2, probability : 0.16666666666667 },
{ _id : 7, type : "card", experimentId :"dak", description : "Draw an ace, then a king", eventNum : 1, probability : 0.07692307692308 },
{ _id : 8, type : "card", experimentId :"dak", description : "Draw an ace, then a king", eventNum : 2, probability : 0.07843137254902 }
] )

단계:

  1. $group을 사용하여 experimentId를 기준으로 그룹화하고 $push를 사용하여 각 이벤트의 확률이 포함된 배열을 만듭니다.

  2. $reduce$multiply를 사용하여 probabilityArr 의 요소들을 곱하고 하나의 값으로 결합하여 프로젝트하는 방법입니다."

db.probability.aggregate(
[
{
$group: {
_id: "$experimentId",
probabilityArr: { $push: "$probability" }
}
},
{
$project: {
description: 1,
results: {
$reduce: {
input: "$probabilityArr",
initialValue: 1,
in: { $multiply: [ "$$value", "$$this" ] }
}
}
}
}
]
)

이 연산은 다음을 반환합니다:

{ _id : "dak", results : 0.00603318250377101 }
{ _id : "r5", results : 0.16666666666667 }
{ _id : "r16", results : 0.027777777777778886 }
{ _id : "d3rc", results : 0.11764705882352879 }

clothes라는 이름의 컬렉션에 다음 문서가 포함되어 있습니다.

db.clothes.insertMany( [
{ _id : 1, productId : "ts1", description : "T-Shirt", color : "black", size : "M", price : 20, discounts : [ 0.5, 0.1 ] },
{ _id : 2, productId : "j1", description : "Jeans", color : "blue", size : "36", price : 40, discounts : [ 0.25, 0.15, 0.05 ] },
{ _id : 3, productId : "s1", description : "Shorts", color : "beige", size : "32", price : 30, discounts : [ 0.15, 0.05 ] },
{ _id : 4, productId : "ts2", description : "Cool T-Shirt", color : "White", size : "L", price : 25, discounts : [ 0.3 ] },
{ _id : 5, productId : "j2", description : "Designer Jeans", color : "blue", size : "30", price : 80, discounts : [ 0.1, 0.25 ] }
] )

각 문서에는 각 항목에 대해 현재 사용 가능한 할인율 쿠폰이 포함된 discounts 배열이 포함되어 있습니다. 각 할인을 제품에 한 번 적용할 수 있는 경우 $reduce를 사용하여 discounts 배열의 각 요소에 대해 (1 - 할인) * 가격 공식을 적용하여 최저가를 계산할 수 있습니다.

db.clothes.aggregate(
[
{
$project: {
discountedPrice: {
$reduce: {
input: "$discounts",
initialValue: "$price",
in: { $multiply: [ "$$value", { $subtract: [ 1, "$$this" ] } ] }
}
}
}
}
]
)

이 연산은 다음을 반환합니다:

{ _id : ObjectId("57c893067054e6e47674ce01"), discountedPrice : 9 }
{ _id : ObjectId("57c9932b7054e6e47674ce12"), discountedPrice : 24.224999999999998 }
{ _id : ObjectId("57c993457054e6e47674ce13"), discountedPrice : 24.224999999999998 }
{ _id : ObjectId("57c993687054e6e47674ce14"), discountedPrice : 17.5 }
{ _id : ObjectId("57c993837054e6e47674ce15"), discountedPrice : 54 }

people라는 이름의 컬렉션에 다음 문서가 포함되어 있습니다.

db.people.insertMany( [
{ _id : 1, name : "Melissa", hobbies : [ "softball", "drawing", "reading" ] },
{ _id : 2, name : "Brad", hobbies : [ "gaming", "skateboarding" ] },
{ _id : 3, name : "Scott", hobbies : [ "basketball", "music", "fishing" ] },
{ _id : 4, name : "Tracey", hobbies : [ "acting", "yoga" ] },
{ _id : 5, name : "Josh", hobbies : [ "programming" ] },
{ _id : 6, name : "Claire" }
] )

다음 예시에서는 hobbies 문자열 배열을 단일 문자열 bio로 축소합니다.

db.people.aggregate(
[
// Filter to return only non-empty arrays
{ $match: { "hobbies": { $gt: [ ] } } },
{
$project: {
name: 1,
bio: {
$reduce: {
input: "$hobbies",
initialValue: "My hobbies include:",
in: {
$concat: [
"$$value",
{
$cond: {
if: { $eq: [ "$$value", "My hobbies include:" ] },
then: " ",
else: ", "
}
},
"$$this"
]
}
}
}
}
}
]
)

이 연산은 다음을 반환합니다:

{ _id : 1, name : "Melissa", bio : "My hobbies include: softball, drawing, reading" }
{ _id : 2, name : "Brad", bio : "My hobbies include: gaming, skateboarding" }
{ _id : 3, name : "Scott", bio : "My hobbies include: basketball, music, fishing" }
{ _id : 4, name : "Tracey", bio : "My hobbies include: acting, yoga" }
{ _id : 5, name : "Josh", bio : "My hobbies include: programming" }

matrices라는 이름의 컬렉션에 다음 문서가 포함되어 있습니다.

db.matrices.insertMany( [
{ _id : 1, arr : [ [ 24, 55, 79 ], [ 14, 78, 35 ], [ 84, 90, 3 ], [ 50, 89, 70 ] ] },
{ _id : 2, arr : [ [ 39, 32, 43, 7 ], [ 62, 17, 80, 64 ], [ 17, 88, 11, 73 ] ] },
{ _id : 3, arr : [ [ 42 ], [ 26, 59 ], [ 17 ], [ 72, 19, 35 ] ] },
{ _id : 4 }
] )

다음 예에서는 2차원 배열을 단일 배열 collapsed로 축소합니다.

db.arrayconcat.aggregate(
[
{
$project: {
collapsed: {
$reduce: {
input: "$arr",
initialValue: [ ],
in: { $concatArrays: [ "$$value", "$$this" ] }
}
}
}
}
]
)

이 연산은 다음을 반환합니다:

{ _id : 1, collapsed : [ 24, 55, 79, 14, 78, 35, 84, 90, 3, 50, 89, 70 ] }
{ _id : 2, collapsed : [ 39, 32, 43, 7, 62, 17, 80, 64, 17, 88, 11, 73 ] }
{ _id : 3, collapsed : [ 42, 26, 59, 17, 72, 19, 35 ] }
{ _id : 4, collapsed : null }

다음 예시에서는 위 예시와 동일한 2차원 배열 축소를 수행하지만, 각 배열의 첫 번째 요소만 포함하는 새 배열을 만듭니다.

db.arrayconcat.aggregate(
[
{
$project: {
results: {
$reduce: {
input: "$arr",
initialValue: [ ],
in: {
collapsed: {
$concatArrays: [ "$$value.collapsed", "$$this" ]
},
firstValues: {
$concatArrays: [ "$$value.firstValues", { $slice: [ "$$this", 1 ] } ]
}
}
}
}
}
}
]
)

이 연산은 다음을 반환합니다:

{ _id : 1, results : { collapsed : [ 24, 55, 79, 14, 78, 35, 84, 90, 3, 50, 89, 70 ], firstValues : [ 24, 14, 84, 50 ] } }
{ _id : 2, results : { collapsed : [ 39, 32, 43, 7, 62, 17, 80, 64, 17, 88, 11, 73 ], firstValues : [ 39, 62, 17 ] } }
{ _id : 3, results : { collapsed : [ 42, 26, 59, 17, 72, 19, 35 ], firstValues : [ 42, 26, 17, 72 ] } }
{ _id : 4, results : null }
← 순위(집계)

이 페이지의 내용