AI 에이전트의 경우: 문서 인덱스는 https://www.mongodb.com/ko-kr/docs/llms.txt에서 사용할 수 있으며, 모든 페이지의 마크다운 버전은 어떤 URL 경로에 .md를 추가하여 사용할 수 있습니다.
Docs Menu

$ 축적자 (축적자 연산자)

$accumulator

Defines a custom accumulator operator. Accumulators are operators that maintain their state (e.g. totals, maximums, minimums, and related data) as documents progress through the pipeline. Use the $accumulator operator to execute your own JavaScript functions to implement behavior not supported by the MongoDB Query Language. See also $function.

$accumulator 이 단계에서 사용할 수 있습니다:

중요

Executing JavaScript inside of an aggregation operator may decrease performance. Only use the $accumulator operator if the provided pipeline operators cannot fulfill your application's needs.

The $accumulator operator has this syntax:

{
$accumulator: {
init: <code>,
initArgs: <array expression>, // Optional
accumulate: <code>,
accumulateArgs: <array expression>,
merge: <code>,
finalize: <code>, // Optional
lang: <string>
}
}
필드
유형
설명

문자열 또는 코드

상태를 초기화하는 데 사용되는 함수입니다. init 함수는 initArgs 배열 표현식에서 인수를 받습니다. 함수 정의를 BSON type 코드 또는 문자열로 지정할 수 있습니다.

init 함수의 형식은 다음과 같습니다.

function (<initArg1>, <initArg2>, ...) {
...
return <initialState>
}

디스크로 유출하거나 샤딩된 클러스터에서 쿼리를 실행하면 축적자가 각각 init()을(를) 호출하여 시작하는 여러 하위 누적의 병합으로 계산될 수 있습니다. init(), accumulate() 및 merge() 함수가 이 실행 모델과 호환되는지 확인합니다.

배열

선택 사항. init 함수에 전달된 인수입니다.

initArgs 의 형식은 다음과 같습니다.

[ <initArg1>, <initArg2>, ... ]

중요: $bucketAuto 단계에서 사용되는 경우 initArgs는 그룹 키를 참조할 수 없습니다(즉, $<fieldName> 구문을 사용할 수 없음). 대신 $bucketAuto 단계에서는 initArgs에 상수 값만 지정할 수 있습니다.

문자열 또는 코드

Function used to accumulate documents. The accumulate function receives its arguments from the current state and accumulateArgs array expression. The result of the accumulate function becomes the new state. You can specify the function definition as either BSON type Code or String.

accumulate 함수의 형식은 다음과 같습니다.

function(state, <accumArg1>, <accumArg2>, ...) {
...
return <newState>
}

배열

accumulate 함수에 전달된 인수입니다. accumulateArgs를 사용하여 accumulate 함수에 전달할 필드 값을 지정할 수 있습니다.

accumulateArgs 의 형식은 다음과 같습니다.

[ <accumArg1>, <accumArg2>, ... ]

문자열 또는 코드

Function used to merge two internal states. merge must be either a String or Code BSON type. merge returns the combined result of the two merged states. For information on when the merge function is called, see Merge Two States with $merge.

merge 함수의 형식은 다음과 같습니다.

function (<state1>, <state2>) {
<logic to merge state1 and state2>
return <newState>
}

문자열 또는 코드

선택 사항. 누적 결과를 업데이트하는 데 사용되는 함수입니다.

finalize 함수의 형식은 다음과 같습니다.

function (state) {
...
return <finalState>
}

문자열

The language used in the $accumulator code.

중요: 현재 lang에 대해서는 js만 지원됩니다.

The following steps outline how the $accumulator operator processes documents:

  1. The operator begins at an initial state, defined by the init function.

  2. 각 문서에 대해 연산자는 누적 함수를 기반으로 상태를 업데이트합니다. 누적 함수의 첫 번째 인수는 현재 상태이며 추가 인수는 accumulateArgs 배열에 지정할 수 있습니다.

  3. When the operator needs to merge multiple intermediate states, it executes the merge function. For more information on when the merge function is called, see Merge Two States with $merge.

  4. finalize 함수가 정의되어 있는 경우 모든 문서가 처리되고 그에 따라 상태가 업데이트되면 finalize 함수가 상태를 최종 출력으로 변환합니다.

As part of its internal operations, the $accumulator operator may need to merge two separate, intermediate states. The merge function specifies how the operator should merge two states.

병합 함수는 항상 한 번에 두 가지 상태를 병합합니다. 세 개 이상의 상태를 병합해야 하는 경우 두 상태의 결과 병합은 단일 상태 로 병합됩니다. 이 프로세스 모든 상태가 병합될 때까지 반복됩니다.

For example, $accumulator may need to combine two states in the following scenarios:

  • $accumulator 샤딩된 클러스터에서 실행됩니다. 연산자는 최종 결과를 얻기 위해 각 샤드의 결과를 병합해야 합니다.

  • A single $accumulator operation exceeds its specified memory limit. If you specify the allowDiskUse option, the operator stores the in-progress operation on disk and finishes the operation in memory. Once the operation finishes, the results from disk and memory are merged together using the merge function.

MongoDB가 init(), accumulate(), merge() 함수에 대해 문서를 처리하는 순서는 다를 수 있으며, $accumulator 함수에 해당 문서가 지정된 순서와 다를 수 있습니다.

예를 들어 _id 필드가 알파벳 문자인 일련의 문서를 생각해 보세요.

{ _id: 'a' },
{ _id: 'b' },
{ _id: 'c' }
...
{ _id: 'z' }

다음으로 _id 필드를 기준으로 문서를 정렬한 다음 $accumulator 함수를 사용하여 _id 필드 값을 연결하는 집계 파이프라인을 고려합니다.

[
{
$sort: { _id: 1 }
},
{
$group: {
_id: null,
alphabet: {
$accumulator: {
init: function() {
return ""
},
accumulate: function(state, letter) {
return(state + letter)
},
accumulateArgs: [ "$_id" ],
merge: function(state1, state2) {
return(state1 + state2)
},
lang: "js"
}
}
}
}
]

MongoDB는 문서가 정렬된 순서로 처리되는 것을 보장하지 않으므로 alphabet 필드가 반드시 abc...z로 설정되는 것은 아닙니다.

이 동작으로 인해 $accumulator 함수가 특정 순서로 문서를 처리하고 반환할 필요가 없는지 확인합니다.

To use $accumulator, you must have server-side scripting enabled.

If you do not use $accumulator (or $function, $where, or mapReduce), disable server-side scripting:

또한 ➤ 보안 구성 옵션으로 MongoDB 실행을 참조하세요.

MongoDB 6.0 upgrades the internal JavaScript engine used for server-side JavaScript, $accumulator, $function, and $where expressions and from MozJS-60 to MozJS-91. Several deprecated, non-standard array and string functions that existed in MozJS-60 are removed in MozJS-91.

이 페이지의 예시는 sample_mflix 데이터 세트의 데이터를 사용합니다. 이 데이터 세트를 자체 관리형 MongoDB 배포서버에 로드하는 방법에 대한 자세한 내용은 샘플 데이터세트 로드를 참조하세요. 샘플 데이터베이스를 수정한 경우, 이 페이지의 예시를 실행하려면 데이터베이스를 제거하고 다시 생성해야 할 수 있습니다.

참고

This example walks through using the $accumulator operator to implement the $avg operator, which is already supported by MongoDB. The goal of this example is not to implement new functionality, but to illustrate the behavior and syntax of the $accumulator operator with familiar logic.

The following operation groups the documents by rated, and uses $accumulator to compute the average imdb.rating for each content rating. The $match stage restricts the input to the G, PG, PG-13, and R content ratings, and excludes documents where imdb.rating is not a double, such as an empty string:

db.movies.aggregate( [
{
$match: {
rated: { $in: [ "G", "PG", "PG-13", "R" ] },
"imdb.rating": { $type: "double" }
}
},
{
$group: {
_id: "$rated",
avgRating: {
$accumulator: {
init: function() { // Set the initial state
return { count: 0, sum: 0 }
},
accumulate: function(state, rating) { // Define how to update the state
return {
count: state.count + 1,
sum: state.sum + rating
}
},
accumulateArgs: [ "$imdb.rating" ], // Argument required by the accumulate function
merge: function(state1, state2) { // When the operator performs a merge,
return { // add the fields from the two states
count: state1.count + state2.count,
sum: state1.sum + state2.sum
}
},
finalize: function(state) { // After collecting the results from all documents,
return (state.sum / state.count) // calculate the average
},
lang: "js"
}
}
}
},
{ $sort: { _id: 1 } }
] )
[
{
_id: 'G',
avgRating: 6.628092243186578
},
{
_id: 'PG',
avgRating: 6.43525917926564
},
{
_id: 'PG-13',
avgRating: 6.404911676001717
},
{
_id: 'R',
avgRating: 6.456657633242984
}
]

The $accumulator defines an initial state where count and sum are both set to 0. For each document that the $accumulator processes, it updates the state by:

  • count를 1씩 증가

  • Adding the values of the document's imdb.rating field to the sum. The accumulate function can access the imdb.rating field because it is passed in the accumulateArgs field.

문서가 처리될 때마다 accumulate 함수는 업데이트된 상태를 반환합니다.

모든 문서가 처리되면 finalize 함수는 등급의 sum을 문서의 count로 나누어 평균을 구합니다. 이렇게 하면 finalize 함수가 모든 문서의 누적 sum 및 count를 수신하기 때문에 실행 계산된 평균을 계속 유지할 필요가 없습니다.

이 작업은 $avg 연산자를 사용하는 다음 파이프라인과 동일합니다.

db.movies.aggregate( [
{
$match: {
rated: { $in: [ "G", "PG", "PG-13", "R" ] },
"imdb.rating": { $type: "double" }
}
},
{
$group: {
_id: "$rated",
avgRating: { $avg: "$imdb.rating" }
}
},
{ $sort: { _id: 1 } }
] )
[
{
_id: 'G',
avgRating: 6.6280922431865825
},
{
_id: 'PG',
avgRating: 6.435259179265659
},
{
_id: 'PG-13',
avgRating: 6.404911676001723
},
{
_id: 'R',
avgRating: 6.456657633242999
}
]

initArgs 옵션을 사용하여 $accumulator의 초기 상태 변경할 수 있습니다. 예시 를 들어 다음과 같은 경우에 유용합니다.

  • 사용자의 상태에 없는 필드 값을 사용하여 사용자의 상태에 영향을 미치거나

  • 처리 중인 그룹에 따라 초기 상태를 다른 값으로 설정합니다.

사용자가 이 데이터를 쿼리 영화를 찾을 수 있는 애플리케이션 허용한다고 가정해 보겠습니다. 사용자가 선호하는 콘텐츠 등급에 대한 결과를 더 많이 표시하는 것이 유용할 수 있습니다. 이 예시 에서, 사용자의 선호 콘텐츠 등급은 PG-13이며, 이는 init 함수에 userProfileRated로 전달됩니다.

다음 집계 파이프라인 groups은 rated에 의해 문서를 작성합니다. 이 작업은 $accumulator를 사용하여 영화의 등급이 사용자 프로필의 등급과 일치하는지 여부에 따라 각 콘텐츠 등급에서 다른 수의 영화를 표시합니다.

참고

다른 기본 콘텐츠 등급으로 이 예시 실행 하려면 initArgs 배열 의 "PG-13"을 "R"와 같은 다른 값으로 바꿉니다.

db.movies.aggregate( [
{
$match: {
rated: { $in: [ "G", "PG", "PG-13", "R" ] },
"imdb.rating": { $type: "double" }
}
},
{
$sort: { "imdb.rating": -1, title: 1 }
},
{
$group: {
_id: { rated: "$rated" },
movies: {
$accumulator: {
init: function(rated, userProfileRated) { // Set the initial state
return {
max: rated === userProfileRated ? 3 : 1, // If the group matches the user's rating,
movies: [] // return 3 movies. Otherwise, return 1.
}
},
initArgs: [ "$rated", "PG-13" ], // Argument to pass to the init function
accumulate: function(state, movieTitle) { // Define how to update the state
if (state.movies.length < state.max) {
state.movies.push(movieTitle);
}
return state;
},
accumulateArgs: [ "$title" ], // Argument required by the accumulate function
merge: function(state1, state2) {
return {
max: state1.max,
movies: state1.movies.concat(state2.movies).slice(0, state1.max)
}
},
finalize: function(state) { // Adjust the state to only return the field we need
return state.movies
},
lang: "js"
}
}
}
},
{ $sort: { "_id.rated": 1 } }
] )
[
{
_id: {
rated: 'G'
},
movies: [
'Modern Times'
]
},
{
_id: {
rated: 'PG'
},
movies: [
'Life'
]
},
{
_id: {
rated: 'PG-13'
},
movies: [
'A Brave Heart: The Lizzie Velasquez Story',
'The Dark Knight',
'The Lord of the Rings: The Return of the King'
]
},
{
_id: {
rated: 'R'
},
movies: [
'The Shawshank Redemption'
]
}
]

init 함수는 max 및 movies 필드를 포함하는 초기 상태 정의합니다. max 필드 해당 특정 그룹 의 최대 영화 수를 설정합니다. 문서의 rated 필드 userProfileRated와 일치하는 경우, 해당 그룹 에는 최대 3개의 동영상이 포함됩니다. 그렇지 않고 문서의 rated 필드 userProfileRated와 일치하지 않으면 그룹 최대 하나의 영화가 포함됩니다.init 함수는 initArgs 배열 에서 rated 및 userProfileRated 인수를 모두 받습니다.

$accumulator가 처리하는 각 문서 에 대해, 해당 제목이 movies의 길이를 max 값 위에 두지 않는 경우 영화의 title를 movies 배열 로 푸시합니다. 문서 처리될 때마다 축적 함수는 업데이트된 상태 를 반환합니다.

병합 함수는 두 상태를 병합하는 방법을 정의합니다. 이 함수는 각 상태 의 movies 배열을 함께 연결하고, 결과 배열 의 길이는 slice() 메서드를 사용하여 제한되어 max 값을 초과하지 않도록 합니다.

모든 문서가 처리되면 finalize 함수는 영화 제목만 반환하도록 결과 상태 수정합니다. 이 함수가 없으면 max 필드 도 출력에 포함되어 애플리케이션 에 대한 요구 사항을 충족하지 못합니다.

이 페이지 평가하기

이 페이지의 내용