집계 빌더
이 페이지의 내용
개요
이 가이드 에서는 MongoDB 코틀린 (Kotlin) 운전자 에서 집계 파이프라인 단계 를 빌드 하는 정적 팩토리 메서드를 제공하는 애그리게이션 클래스를 사용하는 방법을 학습수 있습니다.
애그리게이션에 대한 자세한 소개는 애그리게이션 가이드 를 참조하세요.
이 페이지의 예제에서는 다음 클래스의 메서드에 대한 가져오기를 가정합니다.
Aggregates
Filters
Projections
Sorts
Accumulators
import com.mongodb.client.model.Aggregates import com.mongodb.client.model.Filters import com.mongodb.client.model.Projections import com.mongodb.client.model.Sorts import com.mongodb.client.model.Accumulators
다음 메서드를 사용하여 파이프라인 단계를 구성하고 이를 집계에 목록으로 지정합니다.
val matchStage = Aggregates.match(Filters.eq("someField", "someCriteria")) val sortByCountStage = Aggregates.sortByCount("\$someField") val results = collection.aggregate( listOf(matchStage, sortByCountStage)).toList()
이 가이드의 많은 Aggregation
예제에서는 Atlas sample_mflix.movies 데이터 세트 를 사용합니다. 이 컬렉션의 문서는 Kotlin 드라이버와 함께 사용하기 위해 다음 Movie
데이터 클래스에 의해 모델링됩니다.
data class Movie( val title: String, val year: Int, val genres: List<String>, val rated: String, val plot: String, val runtime: Int, val imdb: IMDB ){ data class IMDB( val rating: Double ) }
match
match()
메서드를 사용하여 수신 문서를 지정된 쿼리 필터와 일치시켜 일치하지 않는 문서를 필터링하는 $match 파이프라인 단계를 만듭니다.
팁
필터는 Bson
을 구현하는 모든 클래스의 인스턴스가 될 수 있지만, Filters 클래스와 결합하여 사용하는 것이 편리합니다. 클래스입니다.
다음 예에서는 필드 title
가 'The Shawshank Redemption'과 동일한 collection movies
의 모든 문서와 일치하는 파이프라인 단계를 만듭니다.
Aggregates.match(Filters.eq(Movie::title.name, "The Shawshank Redemption"))
프로젝트
project()
메서드를 사용하여 지정된 문서 필드를 프로젝션하는 $project 파이프라인 단계를 만듭니다. 애그리게이션에서의 필드 프로젝션은 쿼리에서의 필드 프로젝션과 동일한 규칙을 따릅니다.
팁
이 프로젝션은 Bson
을 구현하는 모든 클래스에 사용할 수 있지만 Projections와 함께 사용하면 편리합니다.
다음 예에서는 title
및 plot
필드를 포함하지만 _id
필드는 제외하는 파이프라인 단계를 만듭니다.
Aggregates.project( Projections.fields( Projections.include(Movie::title.name, Movie::plot.name), Projections.excludeId()) )
계산된 필드 프로젝션
$project
단계는 계산된 필드도 프로젝션할 수 있습니다.
다음 예에서는 rated
필드를 rating
라는 새 필드에 프로젝트하여 필드 이름을 효과적으로 변경하는 파이프라인 단계를 만듭니다.
Aggregates.project( Projections.fields( Projections.computed("rating", "\$${Movie::rated.name}"), Projections.excludeId() ) )
문서
documents()
메서드를 사용하여 입력 값에서 리터럴 문서를 반환하는 $documents 파이프라인 단계를 만듭니다.
중요
집계 파이프라인에서 $documents
단계를 사용하는 경우 해당 단계가 파이프라인의 첫 번째 단계여야 합니다.
다음 예에서는 title
필드가 있는 movies
collection에 샘플 문서를 생성하는 파이프라인 단계를 만듭니다.
Aggregates.documents( listOf( Document(Movie::title.name, "Steel Magnolias"), Document(Movie::title.name, "Back to the Future"), Document(Movie::title.name, "Jurassic Park") ) )
중요
documents()
메서드를 사용하여 집계 파이프라인에 입력을 제공하는 경우 컬렉션이 아니라 데이터베이스에서 aggregate()
메서드를 호출해야 합니다.
val docsStage = database.aggregate<Document>( // ... )
Sample
sample()
메서드를 사용하여 입력에서 문서를 무작위로 선택하는 $sample 파이프라인 단계를 만듭니다.
다음 예시에서는 movies
컬렉션에서 문서 5개를 임의로 선택하는 파이프라인 단계를 만듭니다.
Aggregates.sample(5)
Sort
sort()
메서드를 사용하여 지정된 기준에 따라 정렬하는 $sort 파이프라인 단계를 만듭니다.
팁
이 정렬 기준은 Bson
을 구현하는 모든 클래스에 사용할 수 있지만 Sorts와 함께 사용하면 편리합니다.
다음 예에서는 year
필드 값에 따라 내림차순으로 정렬한 다음 title
필드 값에 따라 오름차순으로 정렬하는 파이프라인 단계를 만듭니다.
Aggregates.sort( Sorts.orderBy( Sorts.descending(Movie::year.name), Sorts.ascending(Movie::title.name) ) )
Skip
skip()
메서드를 사용하여 문서를 다음 단계로 전달하기 전에 지정된 수의 문서를 건너뛰는 $skip 파이프라인 단계를 만듭니다.
다음 예에서는 movies
collection의 첫 5
개 문서를 건너뛰는 파이프라인 단계를 만듭니다.
Aggregates.skip(5)
Limit
$limit 파이프라인 단계를 사용하여 다음 단계로 전달되는 문서 수를 제한합니다.
다음 예에서는 movies
collection에서 반환되는 문서 수를 4
)로 제한하는 파이프라인 단계를 만듭니다.
Aggregates.limit(4)
Lookup
lookup()
메서드를 사용하여 두 컬렉션 간에 조인 및 상관관계가 없는 하위 쿼리를 수행하는 $lookup 파이프라인 단계를 만듭니다.
왼쪽 외부 조인
다음 예에서는 샘플 데이터베이스에서 movies
comments
collection과 collection 간의 왼쪽 외부 조인을 수행하는 파이프라인 단계를 mflix
만듭니다.
movies
의_id
필드를comments
의movie_id
필드에 조인합니다.결과를
joined_comments
필드에 출력합니다.
Aggregates.lookup( "comments", "_id", "movie_id", "joined_comments" )
전체 조인 및 상관관계가 없는 하위 쿼리
다음 예제에서는 가상의 orders
및 warehouses
collection을 사용합니다. 데이터는 다음 Kotlin 데이터 클래스를 사용하여 모델링됩니다.
data class Order( val id: Int, val customerId: Int, val item: String, val ordered: Int ) data class Inventory( val id: Int, val stockItem: String, val inStock: Int )
이 예에서는 항목을 기준으로 두 collection을 연결하는 파이프라인 단계와 inStock
필드의 사용 가능한 수량이 ordered
수량을 충족하기에 충분한지 여부를 생성합니다.
val variables = listOf( Variable("order_item", "\$item"), Variable("order_qty", "\$ordered") ) val pipeline = listOf( Aggregates.match( Filters.expr( Document("\$and", listOf( Document("\$eq", listOf("$\$order_item", "\$${Inventory::stockItem.name}")), Document("\$gte", listOf("\$${Inventory::inStock.name}", "$\$order_qty")) )) ) ), Aggregates.project( Projections.fields( Projections.exclude(Order::customerId.name, Inventory::stockItem.name), Projections.excludeId() ) ) ) val innerJoinLookup = Aggregates.lookup("warehouses", variables, pipeline, "stockData")
Group
group()
메서드를 사용하여 지정된 표현식으로 문서를 그룹화하고 각 개별 그룹화에 대해 문서를 출력하는 $group 파이프라인 단계를 만듭니다.
팁
이 드라이버에는 지원되는 각 축적자에 대한 정적 팩토리 메서드가 있는 Accumulators 클래스가 포함되어 있습니다.
다음 예에서는 customerId
필드 값을 기준으로 orders
collection의 문서를 그룹화하는 파이프라인 단계를 만듭니다. 각 그룹은 ordered
필드 값의 합계와 평균을 totalQuantity
및 averageQuantity
필드에 누적합니다.
Aggregates.group("\$${Order::customerId.name}", Accumulators.sum("totalQuantity", "\$${Order::ordered.name}"), Accumulators.avg("averageQuantity", "\$${Order::ordered.name}") )
축적자 연산자에 대한 자세한 내용은 MongoDB Server 매뉴얼의 축적자 섹션을 참조하세요.
Pick-N 축적자
pick-n 축적자는 특정 순서가 지정된 경우 상위 및 하위 요소를 반환하는 집계 축적 연산자입니다. 집계 축적 연산자를 만들려면 다음 빌더 중 하나를 사용합니다.
팁
MongoDB v5.2 이상을 실행할 때만 이러한 pick-n 축적자를 사용하여 집계 작업을 수행할 수 있습니다.
축적자에 대한 MongoDB Server 매뉴얼 섹션에서 축적자 연산자를 사용할 수 있는 집계 파이프라인 단계를 알아보세요 .
pick-n 축적자 예제에서는 sample-mflix
데이터베이스에 있는 movies
collection의 문서를 사용합니다.
MinN
minN()
빌더는 그룹화의 가장 낮은 n
값을 포함하는 문서의 데이터를 반환하는 $minN 축적자를 만듭니다.
팁
$minN
축적자와 $bottomN
축적자는 유사한 작업을 수행할 수 있습니다. 각 축적자의 권장 사용법은 $minN 축적자와 $bottomN 축적자 비교를 참조하세요.
다음 예에서는 minN()
메서드를 사용하여 imdb.rating
값이 가장 낮은 3개 영화를 year
별로 그룹화하여 반환하는 방법을 보여 줍니다.
Aggregates.group( "\$${Movie::year.name}", Accumulators.minN( "lowestThreeRatings", "\$${Movie::imdb.name}.${Movie.IMDB::rating.name}", 3 ) )
자세한 내용은 minN() API 설명서를 참조하세요.
MaxN
maxN()
축적자는 n
값이 가장 높은 그룹이 포함된 문서의 데이터를 반환합니다.
다음 예에서는 maxN()
메서드를 사용하여 imdb.rating
값이 가장 높은 2개 영화를 year
별로 그룹화하여 반환하는 방법을 보여 줍니다.
Aggregates.group( "\$${Movie::year.name}", Accumulators.maxN( "highestTwoRatings", "\$${Movie::imdb.name}.${Movie.IMDB::rating.name}", 2 ) )
자세한 내용은 maxN() API 설명서를 참조하세요.
FirstN
firstN()
축적자는 지정된 정렬 순서에 따라 각 그룹의 처음 n
개 문서의 데이터를 반환합니다.
팁
$firstN
축적자와 $topN
축적자는 유사한 작업을 수행할 수 있습니다. 각 축적자의 권장 사용법은 $firstN 축적자와 $topN 축적자 비교를 참조하세요.
다음 예에서는 firstN()
메서드를 사용하여 단계에 들어온 순서에 따라 처음 두 영화의 title
값을 year
로 그룹화하여 반환하는 방법을 보여 줍니다.
Aggregates.group( "\$${Movie::year.name}", Accumulators.firstN( "firstTwoMovies", "\$${Movie::title.name}", 2 ) )
자세한 내용은 firstN() API 설명서를 참조하세요.
LastN
lastN()
축적자는 지정된 정렬 순서에 따라 각 그룹에 있는 마지막 n
개 문서의 데이터를 반환합니다.
다음 예에서는 lastN()
메서드를 사용하여 단계에 들어온 순서에 따라 마지막 3개 영화의 title
값을 year
별로 그룹화하여 표시하는 방법을 보여 줍니다.
Aggregates.group( "\$${Movie::year.name}", Accumulators.lastN( "lastThreeMovies", "\$${Movie::title.name}", 3 ) )
자세한 내용은 lastN() API 설명서를 참조하세요.
Top
top()
축적자는 지정된 정렬 순서에 따라 그룹에 있는 첫 번째 문서의 데이터를 반환합니다.
다음 예에서는 top()
메서드를 사용하여 imdb.rating
을 기준으로 최고 평점 영화의 title
및 imdb.rating
값을 year
별로 그룹화하여 반환하는 방법을 보여 줍니다.
Aggregates.group( "\$${Movie::year.name}", Accumulators.top( "topRatedMovie", Sorts.descending("${Movie::imdb.name}.${Movie.IMDB::rating.name}"), listOf("\$${Movie::title.name}", "\$${Movie::imdb.name}.${Movie.IMDB::rating.name}") ) )
자세한 내용은 top() API 설명서를 참조하세요.
TopN
topN()
축적자는 지정된 필드에 대해 n
값이 가장 높은 문서의 데이터를 반환합니다.
팁
$firstN
축적자와 $topN
축적자는 유사한 작업을 수행할 수 있습니다. 각 축적자의 권장 사용법은 $firstN 축적자와 $topN 축적자 비교를 참조하세요.
다음 예에서는 topN()
메서드를 사용하여 runtime
값을 기준으로 상영 시간이 가장 긴 영화 3개의 title
및 runtime
값을 year
별로 그룹화하여 반환하는 방법을 보여 줍니다.
Aggregates.group( "\$${Movie::year.name}", Accumulators.topN( "longestThreeMovies", Sorts.descending(Movie::runtime.name), listOf("\$${Movie::title.name}", "\$${Movie::runtime.name}"), 3 ) )
자세한 내용은 topN() API 설명서를 참조하세요.
Bottom
bottom()
축적자는 지정된 정렬 순서에 따라 그룹에 있는 마지막 문서의 데이터를 반환합니다.
다음 예에서는 bottom()
메서드를 사용하여 runtime
값을 기준으로 상영 시간이 가장 짧은 영화의 title
및 runtime
값을 year
별로 그룹화하여 반환하는 방법을 보여 줍니다.
Aggregates.group( "\$${Movie::year.name}", Accumulators.bottom( "shortestMovies", Sorts.descending(Movie::runtime.name), listOf("\$${Movie::title.name}", "\$${Movie::runtime.name}") ) )
자세한 내용은 bottom() API 설명서를 참조하세요.
BottomN
bottomN()
축적자는 지정된 필드에 대해 n
값이 가장 낮은 문서의 데이터를 반환합니다.
팁
$minN
축적자와 $bottomN
축적자는 유사한 작업을 수행할 수 있습니다. 각 축적자의 권장 사용법은 $minN 축적자와 $bottomN 축적자 비교를 참조하세요.
다음 예에서는 bottomN()
메서드를 사용하여 imdb.rating
값을 기준으로 최저 등급 영화 2개의 title
및 imdb.rating
값을 year
별로 그룹화하여 반환하는 방법을 보여 줍니다.
Aggregates.group( "\$${Movie::year.name}", Accumulators.bottom( "lowestRatedTwoMovies", Sorts.descending("${Movie::imdb.name}.${Movie.IMDB::rating.name}"), listOf("\$${Movie::title.name}", "\$${Movie::imdb.name}.${Movie.IMDB::rating.name}"), ) )
자세한 내용은 bottomN() API 설명서를 참조하세요.
Unwind
unwind()
메서드를 사용하여 입력 문서에서 배열 필드를 분해하고 각 배열 요소에 대한 출력 문서를 생성하는 $unwind 파이프라인 단계를 만듭니다.
다음 예에서는 lowestRatedTwoMovies
배열의 각 요소에 대한 문서를 만듭니다.
Aggregates.unwind("\$${"lowestRatedTwoMovies"}")
배열 필드에 값이 누락되어 있거나, null
값이 있거나, 배열이 비어 있는 문서를 보존하려면 다음을 수행합니다.
Aggregates.unwind( "\$${"lowestRatedTwoMovies"}", UnwindOptions().preserveNullAndEmptyArrays(true) )
배열 인덱스를 포함하려면(이 예제에서는 "position"
필드에):
Aggregates.unwind( "\$${"lowestRatedTwoMovies"}", UnwindOptions().includeArrayIndex("position") )
Out
out()
메서드를 사용하여 동일한 데이터베이스의 지정된 컬렉션에 모든 문서를 쓰는 $out 파이프라인 단계를 만듭니다.
중요
$out
단계는 모든 집계 파이프라인의 마지막 단계여야 합니다.
다음 예에서는 파이프라인의 결과를 classic_movies
컬렉션에 씁니다.
Aggregates.out("classic_movies")
Merge
merge()
메서드를 사용하여 모든 문서를 지정된 컬렉션에 병합하는 $merge 파이프라인 단계를 만듭니다.
중요
$merge
단계는 모든 집계 파이프라인의 마지막 단계여야 합니다.
다음 예에서는 기본 옵션을 사용하여 파이프라인을 nineties_movies
컬렉션에 병합합니다.
Aggregates.merge("nineties_movies")
다음 예에서는 year
및 title
모두가 일치하는 경우 문서를 대체하고, 그렇지 않으면 문서를 삽입하도록 지정하는 몇 가지 기본값이 아닌 옵션을 사용하여 파이프라인을 aggregation
데이터베이스의 movie_ratings
collection에 병합합니다.
Aggregates.merge( MongoNamespace("aggregation", "movie_ratings"), MergeOptions().uniqueIdentifier(listOf("year", "title")) .whenMatched(MergeOptions.WhenMatched.REPLACE) .whenNotMatched(MergeOptions.WhenNotMatched.INSERT) )
GraphLookup
graphLookup()
메서드를 사용하여 지정된 컬렉션에서 재귀 검색을 수행하여 한 문서의 지정된 필드를 다른 문서의 지정된 필드와 일치시키는 $graphLookup 파이프라인 단계를 만듭니다.
다음 예제에서는 contacts
collection을 사용합니다. 데이터는 다음 Kotlin 데이터 클래스를 사용하여 모델링됩니다.
data class Users( val name: String, val friends: List<String>?, val hobbies: List<String>? )
이 예제에서는 friends
필드의 값을 name
필드에 재귀적으로 일치시켜 contact
collection의 사용자에 대한 보고 그래프를 계산합니다.
Aggregates.graphLookup( "contacts", "\$${Users::friends.name}", Users::friends.name, Users::name.name, "socialNetwork" )
원하는 경우 GraphLookupOptions
를 사용하여 반복 사용할 깊이와 깊이 필드의 이름을 지정할 수 있습니다. 이 예에서 $graphLookup
은 최대 두 번 반복되고 모든 문서에 대한 재귀 깊이 정보가 포함된 degrees
필드를 만듭니다.
Aggregates.graphLookup( "contacts", "\$${Users::friends.name}", Users::friends.name, Users::name.name, "socialNetwork", GraphLookupOptions().maxDepth(2).depthField("degrees") )
GraphLookupOptions
을 사용하면 MongoDB에서 검색에 문서가 포함되도록 문서를 일치시키는 필터를 지정할 수 있습니다. 이 예에서는 hobbies
필드에 '골프'가 포함된 링크만 포함됩니다.
Aggregates.graphLookup( "contacts", "\$${Users::friends.name}", Users::friends.name, Users::name.name, "socialNetwork", GraphLookupOptions().maxDepth(1).restrictSearchWithMatch( Filters.eq(Users::hobbies.name, "golf") ) )
SortByCount
sortByCount()
메서드를 사용하여 지정된 표현식을 기준으로 문서를 그룹화한 다음 이러한 그룹을 내림차순으로 카운트별로 정렬하는 $sortByCount 파이프라인 단계를 만듭니다.
팁
$sortByCount
단계는 $sum
축적자가 포함되어 있고 그 다음 단계가 $sort
인 $group
단계와 동일합니다.
[ { "$group": { "_id": <expression to group on>, "count": { "$sum": 1 } } }, { "$sort": { "count": -1 } } ]
다음 예에서는 movies
collection의 문서를 genres
필드를 기준으로 그룹화하고 각 고유 값의 개수를 계산합니다.
Aggregates.sortByCount("\$${Movie::genres.name}"),
ReplaceRoot
replaceRoot()
메서드를 사용하여 각 입력 문서를 지정된 문서로 대체하는 $replaceRoot 파이프라인 단계를 만듭니다.
다음 예시에서는 다음 Kotlin 데이터 클래스를 사용하여 모델링된 데이터가 포함된 가상의 books
collection을 사용합니다.
data class Libro(val titulo: String) data class Book(val title: String, val spanishTranslation: Libro)
각 입력 문서는 spanishTranslation
필드에 중첩된 문서로 대체됩니다.
Aggregates.replaceRoot("\$${Book::spanishTranslation.name}")
AddFields
addFields()
메서드를 사용하여 문서에 새 필드를 추가하는 $addFields 파이프라인 단계를 만듭니다.
팁
필드 포함 또는 제외를 프로젝션하지 않으려면 $addFields
를 사용합니다.
다음 예제에서는 movie
collection의 입력 문서에 두 개의 새 필드 watched
및 type
를 추가합니다.
Aggregates.addFields( Field("watched", false), Field("type", "movie") )
Count
count()
메서드를 사용하여 단계에 들어가는 문서 수를 계산하고 해당 값을 지정된 필드 이름에 할당하는 $count 파이프라인 단계를 만듭니다. 필드를 지정하지 않으면 count()
는 기본적으로 필드 이름을 "count"로 설정합니다.
팁
$count
단계는 다음에 대한 신택틱 슈거(Syntactic Sugar)입니다.
{ "$group":{ "_id": 0, "count": { "$sum" : 1 } } }
다음 예에서는 'total' 필드의 수신 문서 수를 출력하는 파이프라인 단계를 만듭니다.
Aggregates.count("total")
Bucket
bucket()
메서드를 사용하여 미리 정의된 경계 값을 중심으로 데이터 버킷을 자동화하는 $bucket 파이프라인 단계를 만듭니다.
다음 예시에서는 다음 Kotlin 데이터 클래스로 모델링된 데이터를 사용합니다.
data class Screen( val id: String, val screenSize: Int, val manufacturer: String, val price: Double )
이 예에서는 screenSize
필드의 값(하한선은 포함하고 상한선은 제외)을 기준으로 수신 문서를 그룹화하는 파이프라인 단계를 만듭니다.
Aggregates.bucket("\$${Screen::screenSize.name}", listOf(0, 24, 32, 50, 70, 1000))
BucketOptions
클래스를 사용하여 지정된 경계를 벗어난 값에 대한 기본 버킷을 지정하고 추가적인 축적자를 지정할 수 있습니다.
다음 예에서는 screenSize
필드 값을 기준으로 수신 문서를 그룹화하고, 각 버킷에 속하는 문서 수를 계산하여, screenSize
값을 matches
라는 필드에 넣고, 화면 크기가 '70' 보다 큰 경우 'monster'라는 버킷에 캡처하여 엄청나게 큰 화면 크기로 저장하는 파이프라인 단계를 만듭니다.
팁
이 드라이버에는 지원되는 각 축적자에 대한 정적 팩토리 메서드가 있는 Accumulators 클래스가 포함되어 있습니다.
Aggregates.bucket("\$${Screen::screenSize.name}", listOf(0, 24, 32, 50, 70), BucketOptions() .defaultBucket("monster") .output( Accumulators.sum("count", 1), Accumulators.push("matches", "\$${Screen::screenSize.name}") ) )
BucketAuto
bucketAuto()
메서드를 사용하여 지정된 수의 버킷에 문서를 균등하게 배포하려고 시도할 때 각 버킷의 경계를 자동으로 결정하는 $bucketAuto 파이프라인 단계를 만듭니다.
다음 예시에서는 다음 Kotlin 데이터 클래스로 모델링된 데이터를 사용합니다.
data class Screen( val id: String, val screenSize: Int, val manufacturer: String, val price: Double )
이 예에서는 price
필드 값을 사용하여 문서를 생성하고 5개의 버킷에 균등하게 배포하는 파이프라인 단계를 생성합니다.
Aggregates.bucketAuto("\$${Screen::screenSize.name}", 5)
BucketAutoOptions
클래스를 사용하여 기본 숫자 기반의 체계를 지정하여 경계 값을 설정하고 추가적인 축적자를 지정합니다.
다음 예에서는 price
필드 값을 사용하여 문서를 생성하고 5개의 버킷에 균등하게 배포하는 파이프라인 단계를 만들고, 버킷 경계를 2의 거듭제곱(2, 4, 8, 16, ...)으로 설정합니다. . 또한 각 버킷의 문서 수를 계산하고 avgPrice
라는 새 필드에서 평균 price
를 계산합니다.
팁
이 드라이버에는 지원되는 각 축적자에 대한 정적 팩토리 메서드가 있는 Accumulators 클래스가 포함되어 있습니다.
Aggregates.bucketAuto( "\$${Screen::price.name}", 5, BucketAutoOptions() .granularity(BucketGranularity.POWERSOF2) .output(Accumulators.sum("count", 1), Accumulators.avg("avgPrice", "\$${Screen::price.name}")) )
패싯
facet()
메서드를 사용하여 병렬 파이프라인을 정의할 수 있는 $facet 파이프라인 단계를 만듭니다.
다음 예시에서는 다음 Kotlin 데이터 클래스로 모델링된 데이터를 사용합니다.
data class Screen( val id: String, val screenSize: Int, val manufacturer: String, val price: Double )
이 예에서는 두 개의 병렬 애그리게이션을 실행하는 파이프라인 단계를 생성합니다.
첫 번째 집계는 수신 문서를
screenSize
필드에 따라 5개 그룹으로 배포합니다.두 번째 애그리게이션은 모든 제조업체를 계산하고 상위 5개로 제한되는 개수를 반환합니다.
Aggregates.facet( Facet( "Screen Sizes", Aggregates.bucketAuto( "\$${Screen::screenSize.name}", 5, BucketAutoOptions().output(Accumulators.sum("count", 1)) ) ), Facet( "Manufacturer", Aggregates.sortByCount("\$${Screen::manufacturer.name}"), Aggregates.limit(5) ) )
SetWindowFields
setWindowFields()
메서드를 사용하여 기간 연산자를 통해 컬렉션의 지정된 기간 범위의 문서에서 작업을 수행할 수 있는 $setWindowFields 파이프라인 단계를 만듭니다.
다음 예제에서는 다음 Kotlin 데이터 클래스로 모델링된 데이터를 사용하여 가상의 weather
collection을 사용합니다.
data class Weather( val localityId: String, val measurementDateTime: LocalDateTime, val rainfall: Double, val temperature: Double )
이 예에서는 rainfall
및 temperature
필드에 표시된 보다 세분화된 측정값을 바탕으로 각 지역의 지난 달 누적 강우량과 평균 기온을 계산하는 파이프라인 단계를 만듭니다.
val pastMonth = Windows.timeRange(-1, MongoTimeUnit.MONTH, Windows.Bound.CURRENT) val resultsFlow = weatherCollection.aggregate<Document>( listOf( Aggregates.setWindowFields("\$${Weather::localityId.name}", Sorts.ascending(Weather::measurementDateTime.name), WindowOutputFields.sum( "monthlyRainfall", "\$${Weather::rainfall.name}", pastMonth ), WindowOutputFields.avg( "monthlyAvgTemp", "\$${Weather::temperature.name}", pastMonth ) ) )
Densify
densify()
메서드를 사용하여 지정된 간격에 걸쳐 일련의 문서 시퀀스를 생성하는 $densify 파이프라인 단계를 만듭니다.
팁
$densify()
집계 단계는 MongoDB v5.1 이상을 실행하는 경우에만 사용할 수 있습니다.
1시간 간격으로 유사한 position
필드에 대한 측정값이 포함된 Atlas 샘플 날씨 데이터 세트 에서 검색한 다음 문서를 가정해 보겠습니다.
Document{{ _id=5553a..., position=Document{{type=Point, coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:00:00 EST 1984, ... }} Document{{ _id=5553b..., position=Document{{type=Point, coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 09:00:00 EST 1984, ... }}
이러한 문서는 다음 Kotlin 데이터 클래스를 사용하여 모델링됩니다.
data class Weather( val id: ObjectId = ObjectId(), val position: Point, val ts: LocalDateTime )
이러한 문서에서 아래의 조치를 수행하는 파이프라인 단계를 생성해야 한다고 가정해 보겠습니다.
ts
값이 아직 존재하지 않는 경우 15분 간격으로 문서를 추가합니다.position
필드를 기준으로 문서를 그룹화합니다.
이러한 조치를 수행하는 densify()
집계 단계 빌더에 대한 호출은 다음과 유사해야 합니다.
Aggregates.densify( "ts", DensifyRange.partitionRangeWithStep(15, MongoTimeUnit.MINUTE), DensifyOptions.densifyOptions().partitionByFields("Position.coordinates") )
다음 출력에는 기존 문서 간에 15분마다 ts
값을 포함하는 애그리게이션 단계에서 생성된 문서가 강조되어 있습니다.
Document{{ _id=5553a..., position=Document{{type=Point, coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:00:00 EST 1984, ... }} Document{{ position=Document{{coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:15:00 EST 1984 }} Document{{ position=Document{{coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:30:00 EST 1984 }} Document{{ position=Document{{coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:45:00 EST 1984 }} Document{{ _id=5553b..., position=Document{{type=Point, coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 09:00:00 EST 1984, ... }}
자세한 내용은 densify 패키지 API 설명서를 참조하세요.
Fill
fill()
메서드를 사용하여 null
및 누락된 필드 값을 채우는 $fill 파이프라인 단계를 만듭니다.
팁
$fill()
집계 단계는 MongoDB v5.3 이상을 실행하는 경우에만 사용할 수 있습니다.
시간별 온도 및 기압 측정 값이 포함된 다음 문서를 고려합니다.
Document{{_id=6308a..., hour=1, temperature=23C, air_pressure=29.74}} Document{{_id=6308b..., hour=2, temperature=23.5C}} Document{{_id=6308c..., hour=3, temperature=null, air_pressure=29.76}}
이러한 문서는 다음 Kotlin 데이터 클래스를 사용하여 모델링됩니다.
data class Weather( val id: ObjectId = ObjectId(), val hour: Int, val temperature: String?, val air_pressure: Double? )
다음과 같이 문서에서 누락된 온도 및 기압 데이터 포인트를 채워야 한다고 가정해 보겠습니다.
선형 보간법을 사용하여 '2' 시간에 대한
air_pressure
필드를 채워 값을 계산합니다.누락된
temperature
값을 '3' 시간에 대해 '23.6C'로 설정합니다.
이러한 조치를 수행하는 fill()
집계 단계 빌더에 대한 호출은 다음과 유사합니다.
val resultsFlow = weatherCollection.aggregate<Weather>( listOf( Aggregates.fill( FillOptions.fillOptions().sortBy(Sorts.ascending(Weather::hour.name)), FillOutputField.value(Weather::temperature.name, "23.6C"), FillOutputField.linear(Weather::air_pressure.name) ) ) ) resultsFlow.collect { println(it) }
Weather(id=6308a..., hour=1, temperature=23C, air_pressure=29.74) Weather(id=6308b..., hour=2, temperature=23.5C, air_pressure=29.75) Weather(id=6308b..., hour=3, temperature=23.6C, air_pressure=29.76)
자세한 내용은 fill 패키지 API 설명서를 참조하세요.
Atlas 전체 텍스트 검색
search()
메서드를 사용하여 하나 이상의 필드에 대한 전체 텍스트 검색을 지정하는 $search 파이프라인 단계를 만듭니다.
팁
MongoDB Atlas v4.2 이상에서만 사용 가능
이 집계 파이프라인 연산자는4.2 Atlas Search 인덱스 가 적용되는 v 이상을 실행하는 MongoDB Atlas 클러스터에 호스팅되는 컬렉션에만 사용할 수 있습니다. 이 연산자의 필수 설정 및 기능에 대한 자세한 내용은 Atlas Search 설명서를 참조하세요.
다음 예에서는 movies
컬렉션의 title
필드에서 "Future"라는 단어가 포함된 텍스트를 검색하는 파이프라인 단계를 만듭니다.
Aggregates.search( SearchOperator.text( SearchPath.fieldPath(Movie::title.name), "Future" ), SearchOptions.searchOptions().index("title") )
Atlas Search API 패키지 문서에서 빌더에 대해 자세히 알아보세요.
Atlas Search 메타데이터
searchMeta()
메서드를 사용하여 Atlas 전체 텍스트 검색 쿼리에서 결과의 메타데이터 부분만 반환하는 $searchMeta 파이프라인 단계를 만듭니다.
팁
MongoDB Atlas v4.4.11 이상에서만 사용 가능
이 집계 파이프라인 연산자는 v4.4.11 이상을 실행하는 MongoDB Atlas 클러스터에서만 사용할 수 있습니다. 사용 가능한 버전에 대한 자세한 목록은 $searchMeta에 대한 MongoDB Atlas 설명서를 참조하세요.
다음 예에서는 Atlas Search 집계 단계의 count
메타데이터를 보여 줍니다.
Aggregates.searchMeta( SearchOperator.near(1985, 2, SearchPath.fieldPath(Movie::year.name)), SearchOptions.searchOptions().index("year") )
searchMeta() API 문서에서이 헬퍼에 대해 자세히 알아보세요.
Atlas Vector Search
중요
이 기능을 지원하는 MongoDB Atlas 버전에 대한 자세한 내용은 Atlas 설명서의 제한 사항 을 참조하세요.
vectorSearch()
메서드를 사용하여 시맨틱 Atlas Search 를 지정하는 $vectorSearch 파이프라인 단계를 만듭니다. 시맨틱 Atlas Search는 의미가 유사한 정보를 찾는 Atlas Search의 한 유형입니다.
컬렉션에서 애그리게이션을 수행할 때 이 기능을 사용하려면 벡터 Atlas Search 인덱스를 만들고 벡터 임베딩을 인덱싱해야 합니다. 에서 Atlas Search 인덱스를 설정하는 방법을 알아보려면 설명서에서 MongoDB Atlas Vector Atlas Search를 위한 벡터 임베딩을 인덱스하는 Atlas 방법을 참조하세요.
이 섹션의 예제에서는 다음 Kotlin 데이터 클래스로 모델링된 데이터를 사용합니다.
data class MovieAlt( val title: String, val year: Int, val plot: String, val plotEmbedding: List<Double> )
이 예시 에서는 vectorSearch()
메서드를 사용하여 다음 사양으로 정확한 벡터 검색 을 수행하는 집계 파이프라인 을 빌드 하는 방법을 보여 줍니다.
문자열 값의 벡터 임베딩을 사용하여
plotEmbedding
필드 값을 검색합니다.mflix_movies_embedding_index
벡터 검색 인덱스 사용문서 1개 반환
year
값이2016
이상인 문서를 필터링합니다.
Aggregates.vectorSearch( SearchPath.fieldPath(MovieAlt::plotEmbedding.name), listOf(-0.0072121937, -0.030757688, -0.012945653), "mflix_movies_embedding_index", 1.toLong(), exactVectorSearchOptions().filter(Filters.gte(MovieAlt::year.name, 2016)) )
이 도우미에 대해 자세히 알아보려면 vectorSearch() API 설명서를 참조하세요.