对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。

聚合构建器

在本指南中,您可以学习如何使用 Aggregates 类,该类提供了在 MongoDB Kotlin 驱动程序中构建 聚合管道阶段 的静态工厂方法。

有关聚合的更全面介绍,请参阅我们的聚合指南。

本页上的示例假定导入了以下类的方法:

  • Aggregates

  • Filters

  • Projections

  • Sorts

  • Accumulators

import com.mongodb.client.model.Aggregatesimport com.mongodb.client.model.Filtersimport com.mongodb.client.model.Projectionsimport com.mongodb.client.model.Sortsimport 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 数据集。 此集合中的文档由以下Movie数据类进行建模,以与 Kotlin 驱动程序一起使用:

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, val fullplot: String? = "No full plot",){ data class IMDB( val rating: Double )}

提示

构建器方法和数据类属性

通过将可选的Kotlin驱动程序扩展依赖项添加到应用程序,您可以直接将构建者类中的方法与数据类属性一起使用。要学习;了解更多信息和查看示例,请参阅《使用构建器与数据类》指南。

使用 match() 方法创建 $match 管道阶段,根据指定的查询筛选条件匹配传入的文档,筛选掉不匹配的文档。

提示

筛选器可以是任何实现Bson的类的实例,但与Filters类结合使用会很方便。 类。

以下示例创建了一个管道阶段,用于匹配collection集合中的所有文档,其中字段等于movies title"The Shawshank Redemption":

Aggregates.match(Filters.eq(Movie::title.name, "The Shawshank Redemption"))

使用project()方法创建用于投影指定文档字段的$project管道阶段。 聚合中的字段投影遵循与查询中的字段投影相同的规则。

提示

虽然投影可以是任何实现 Bson 的类的实例,但结合使用投影还是很方便的。

以下示例创建了一个管道阶段,其中包括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 阶段,则必须是管道中的第一个阶段。

以下示例创建了一个管道阶段,该阶段在movies集合中创建带有title字段的示例文档:

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 管道阶段,从输入中随机选择文档。

以下示例创建一个管道阶段,用于从 movies 集合中随机选择 5 个文档:

Aggregates.sample(5)

使用 sort() 方法创建 $sort 管道阶段,根据指定条件进行排序。

提示

虽然排序条件可以是任何实现 Bson 的类的实例,但结合使用 Sorts 还是很方便的。

以下示例创建了管道阶段,根据 year 字段的值以降序排序,然后根据 title 字段的值以升序排序:

Aggregates.sort( Sorts.orderBy( Sorts.descending(Movie::year.name), Sorts.ascending(Movie::title.name) ))

使用 skip() 方法创建一个 $skip 管道阶段,以在将文档传递到下一阶段之前跳过指定数量的文档。

以下示例创建了一个管道阶段,用于跳过collection中的前5 movies个文档:

Aggregates.skip(5)

使用 $limit 管道阶段来限制传递到下一阶段的文档数量。

以下示例创建了一个管道阶段,将从collection返回的文档数量限制为movies 4:

Aggregates.limit(4)

使用 lookup() 方法创建 $lookup 管道阶段,在两个集合之间执行连接和非相关子查询。

以下示例创建了一个管道阶段,用于在示例mflix数据库中的movies和commentscollection之间执行左外连接:

  1. 它将 movies 中的 _id 字段与 comments 中的 movie_id 字段连接起来

  2. 它会在 joined_comments 字段中输出结果

Aggregates.lookup( "comments", "_id", "movie_id", "joined_comments")

以下示例使用了虚构的orders和warehousescollection。数据使用以下 Kotlin 数据类进行建模:

data class Order( @BsonId val id: Int, val customerId: Int, val item: String, val ordered: Int)data class Inventory( @BsonId val id: Int, val stockItem: String, val inStock: Int)

该示例创建了一个管道阶段,用于根据商品以及inStock字段中的可用数量是否足以满足ordered数量来连接两个collection:

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 管道阶段,根据指定表达式对文档分组,并为每个不同分组输出一个文档。

提示

驱动程序包含“累加器”类,该类为每个支持的累加器提供静态工厂方法。

orderscustomerId以下示例创建了一个管道阶段,该阶段按字段的值对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 累加器是聚合累加操作符,在特定排序的情况下返回顶部和底部元素。使用下列生成器之一创建聚合累加操作符:

提示

只有在运行 MongoDB v5.2 或更高版本时,才能使用这些 pick-n 累加器执行聚合操作。

从MongoDB Server手册中有关累加器的部分,了解可以将累加器操作符与哪些聚合管道阶段一起使用。

pick-n 累加器示例使用sample-mflix数据库中moviescollection的文档。

minN()构建器创建$minN累加器,该累加器从包含n个分组最低值的文档中返回数据。

提示

$minN和$bottomN累加器可执行类似任务。 有关每个累加器的建议用法,请参阅$minN 和 $bottomN 累加器的比较。

以下示例演示了如何使用 minN() 方法返回电影的三个最低 imdb.rating 值,并按 year 进行分组:

Aggregates.group( "\$${Movie::year.name}", Accumulators.minN( "lowestThreeRatings", "\$${Movie::imdb.name}.${Movie.IMDB::rating.name}", 3 ))

请参阅 minN() API 文档了解更多信息。

maxN() 累加器从包含分组中 n 个最高值的文档中返回数据。

以下示例演示了如何使用 maxN() 方法返回电影的两个最高 imdb.rating 值,并按 year 进行分组:

Aggregates.group( "\$${Movie::year.name}", Accumulators.maxN( "highestTwoRatings", "\$${Movie::imdb.name}.${Movie.IMDB::rating.name}", 2 ))

请参阅 maxN() API 文档了解更多信息。

firstN() 累加器返回指定排序顺序的每个分组中前 n 个文档的数据。

提示

$firstN和$topN累加器可执行类似任务。 有关每个累加器的建议用法,请参阅$firstN 和 $topN 累加器的比较。

以下示例演示了如何使用firstN()方法根据电影进入舞台的顺序返回前两个电影title值,并按year分组:

Aggregates.group( "\$${Movie::year.name}", Accumulators.firstN( "firstTwoMovies", "\$${Movie::title.name}", 2 ))

请参阅 firstN() API 文档了解更多信息。

lastN() 累加器返回指定排序顺序的每个分组中最后 n 个文档的数据。

以下示例演示了如何使用 lastN() 方法根据电影进入舞台的顺序显示最后三个电影 title 值,并按 year 分组:

Aggregates.group( "\$${Movie::year.name}", Accumulators.lastN( "lastThreeMovies", "\$${Movie::title.name}", 3 ))

请参阅 lastN() API 文档了解更多信息。

top() 累加器会根据指定的排序顺序,返回分组中第一个文档的数据。

以下示例演示了如何使用 top() 方法返回基于 imdb.rating 且按 year 分组的评分最高电影的 title 和 imdb.rating 值。

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() 累加器会从包含指定字段最高 n 值的文档中返回数据。

提示

$firstN和$topN累加器可执行类似任务。 有关每个累加器的建议用法,请参阅$firstN 和 $topN 累加器的比较。

以下示例演示如何使用 topN() 方法根据 runtime 值返回长度排名前三的电影的 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() 方法根据 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() 累加器会从包含指定字段最低 n 值的文档中返回数据。

提示

$minN和$bottomN累加器可执行类似任务。 有关每个累加器的建议用法,请参阅$minN 和 $bottomN 累加器的比较。

以下示例演示了如何使用 bottomN() 方法根据 imdb.rating 值返回评分最低的两部电影的 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}"), ))

请参阅 bottom() API 文档了解更多信息。

使用 unwind() 方法创建 $unwind 管道阶段,从输入文档解构数组字段,为每个数组元素创建输出文档。

以下示例为 lowestRatedTwoMovies 数组中的每个元素创建了文档:

Aggregates.unwind("\$${"lowestRatedTwoMovies"}")

要保留数组字段缺失或数组字段的 null 值为空的文档,请执行以下操作:

Aggregates.unwind( "\$${"lowestRatedTwoMovies"}", UnwindOptions().preserveNullAndEmptyArrays(true))

要包含数组索引(在本示例中,在名为"position"的字段中):

Aggregates.unwind( "\$${"lowestRatedTwoMovies"}", UnwindOptions().includeArrayIndex("position"))

使用 out() 方法创建 $out 管道阶段,将所有文档写入同一数据库中的指定集合。

重要

$out 阶段必须是任何聚合管道中的最后一个阶段。

以下示例将管道结果写入 classic_movies 集合:

Aggregates.out("classic_movies")

使用 merge() 方法创建 $merge 管道阶段,将所有文档合并到指定的集合中。

重要

$merge 阶段必须是任何聚合管道中的最后一个阶段。

以下示例使用默认选项将管道合并到 nineties_movies 集合中:

Aggregates.merge("nineties_movies")

以下示例使用一些非默认选项将管道合并到aggregation数据库中的movie_ratingscollection中,这些非默认选项指定,如果year和title都匹配,则替换文档,否则插入文档:

Aggregates.merge( MongoNamespace("aggregation", "movie_ratings"), MergeOptions().uniqueIdentifier(listOf("year", "title")) .whenMatched(MergeOptions.WhenMatched.REPLACE) .whenNotMatched(MergeOptions.WhenNotMatched.INSERT))

使用 graphLookup() 方法创建 $graphLookup 管道阶段,对指定集合执行递归搜索,以将一个文档中的指定字段与另一个文档的指定字段进行匹配。

以下示例使用contactscollection。使用以下 Kotlin 数据类对数据进行建模:

data class Users( val name: String, val friends: List<String>?, val hobbies: List<String>?)

contact该示例计算collection中用户的报告图表,以递归方式将字段中的值与friends name字段进行匹配:

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字段包含“golf”的链接才会包含在内:

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 阶段与带有 $sum 累加器的 $group 阶段相同,之后是 $sort 阶段。

[ { "$group": { "_id": <expression to group on>, "count": { "$sum": 1 } } }, { "$sort": { "count": -1 } }]

moviesgenres以下示例按字段对collection中的文档进行分组,并计算每个非重复值的计数:

Aggregates.sortByCount("\$${Movie::genres.name}"),

使用 replaceRoot() 方法创建 $replaceRoot 管道阶段,用指定文档替换每个输入文档。

以下示例使用一个虚构的bookscollection,其中包含使用以下 Kotlin 数据类建模的数据:

data class Libro(val titulo: String)data class Book(val title: String, val spanishTranslation: Libro)

每个输入文档都被spanishTranslation字段中的嵌套文档替换:

Aggregates.replaceRoot("\$${Book::spanishTranslation.name}")

使用 addFields() 方法创建 $addFields 管道阶段,为文档添加新字段。

提示

不想对字段包含或排除进行投影时,请使用 $addFields。

以下示例将两个新字段watched 和type movie添加到collection的输入文档中:

Aggregates.addFields( Field("watched", false), Field("type", "movie"))

使用count()方法创建$count管道阶段,用于计算进入该阶段的文档数量,并将该值分配给指定的字段名称。 如果未指定字段, count()将默认字段名称为“计数”。

提示

$count 阶段是语法糖,用于:

{ "$group":{ "_id": 0, "count": { "$sum" : 1 } } }

以下示例创建了管道阶段,在名为“总计”的字段中输出传入文档的计数:

Aggregates.count("total")

使用 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”的存储桶中,用于超大屏幕尺寸:

提示

驱动程序包含“累加器”类,该类为每个支持的累加器提供静态工厂方法。

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 管道阶段,自动确定每个存储桶的边界,试图将文档平均分配到指定数量的存储桶中。

以下示例使用通过以下 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...) 。 它还计算每个存储桶中的文档数量,并在名为 的新字段中计算它们的平均值price avgPrice:

提示

驱动程序包含“累加器”类,该类为每个支持的累加器提供静态工厂方法。

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 管道阶段,允许使用窗口操作符对集合中指定跨度的文档执行操作。

提示

窗口功能

该驱动程序包含 Windows 类,并附带用于构造窗口化计算的静态工厂方法。

以下示例使用一个虚构的weathercollection,该collection使用通过以下 Kotlin 数据类建模的数据:

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 管道阶段,生成跨越指定时间间隔的文档序列。

提示

只有在运行 MongoDB v5.1 或更高版本时,才能使用 $densify() 聚合阶段。

考虑从Atlas 样本天气数据集中检索到的以下文档,其中包含类似position字段的测量值,测量间隔为一小时:

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( @BsonId val id: ObjectId = ObjectId(), val position: Point, val ts: LocalDateTime)

假设需要创建管道阶段,对这些文档执行以下操作:

  • 每隔 15 分钟添加一个尚未存在 ts 值的文档。

  • 按 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, ... }}

请参阅使软件包 API 文档密集化,了解更多信息。

使用fill()方法创建填充null和缺失字段值的$fill管道阶段。

提示

只有在运行 MongoDB v5.3 或更高版本时,才能使用 $fill() 聚合阶段。

以下文档包含每小时的温度和气压测量值:

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( @BsonId val id: ObjectId = ObjectId(), val hour: Int, val temperature: String?, val air_pressure: Double?)

假设您需要在文档中填充缺失的温度和气压数据点,如下所示:

  • 使用线性插值填充小时“2”的 air_pressure 字段来计算值。

  • 将缺失的 temperature 值设置为“23.6C”时间为“3”小时。

调用 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)

请参阅填充软件包 API 文档,了解更多信息。

使用 search() 方法来创建 $search 管道阶段,从而指定针对一个或多个字段的全文搜索。

提示

仅适用于 Atlas for MongoDB v4.2 及更高版本

此聚合管道操作符仅适用于在运行v4.2或更高版本的MongoDB Atlas集群上托管且由MongoDB 搜索索引覆盖的集合。从MongoDB 搜索文档中了解有关此操作符所需的设置和功能的更多信息。

titlemovies以下示例创建了一个管道阶段,该阶段在collection中的字段中搜索包含“Future”一词的文本:

Aggregates.search( SearchOperator.text( SearchPath.fieldPath(Movie::title.name), "Future" ), SearchOptions.searchOptions().index("title"))

通过搜索包API文档了解详情有关构建者的更多信息。

Kotlin驱动程序为以下操作符提供了辅助方法:

Operator
说明

从不完整输入字符串中搜索包含字符序列的单词或短语。

将两个或多个操作符组合到一个查询中。

检查字段是否与您指定的值匹配。映射到 equals() 和 equalsNull() 方法。

测试指定索引字段名称的路径在文档中是否存在。

在给定路径搜索由BSON数字、日期、布尔值、ObjectId、uuid 或字符串值组成的大量,并返回该字段的值等于指定大量中任意值的文档。

返回与输入文档类似的文档。

支持对数字、日期和GeoJSON point值进行查询和评分。

使用索引配置中指定的分析器搜索包含有序术语序列的文档。

支持查询索引字段和值的组合。

支持对数字、日期和字符串值进行查询和评分。 映射到 numberRange() 和 dateRange() 方法。

将查询字段解释为正则表达式。

使用在索引配置中指定的分析器执行全文搜索。

启用在搜索字符串中使用可匹配任何字符的特殊字符的查询。

在运行此示例之前,您必须在具有以下定义的 movies 集合上创建 MongoDB 搜索索引:

{ "mappings": { "dynamic": true, "fields": { "title": { "analyzer": "lucene.keyword", "type": "string" }, "genres": { "normalizer": "lowercase", "type": "token" } } }}

要学习;了解有关创建 MongoDB 搜索索引的更多信息,请参阅索引指南中的 MongoDB 搜索和 MongoDB Vector Search 索引 部分。

以下代码创建具有以下规范的 $search 阶段:

  • 检查 genres大量是否包含 "Comedy"

  • 在 fullplot 字段中搜索字段"new york"

  • 匹配介于 1950 和 2000(含)之间的 year 值

  • 搜索以术语"Love" 开头的 title 值

data class Results(val title: String, val year: Int, val genres: List<String>) val searchStage = Aggregates.search( SearchOperator.compound() .filter( listOf( SearchOperator.`in`(SearchPath.fieldPath(Movie::genres.name), listOf("Comedy")), SearchOperator.phrase(SearchPath.fieldPath(Movie::fullplot.name), "new york"), SearchOperator.numberRange(SearchPath.fieldPath(Movie::year.name)).gtLt(1950, 2000), SearchOperator.wildcard(SearchPath.fieldPath(Movie::title.name), "Love *") ) )) val projectStage = Aggregates.project( Projections.include(Movie::title.name, Movie::year.name, Movie::genres.name)) val pipeline = listOf(searchStage, projectStage)val resultsFlow = ftsCollection.aggregate<Results>(pipeline) resultsFlow.collect { println(it) }

要学习有关MongoDB 搜索辅助程序方法的更多信息,请参阅驱动程序 Core API 文档中的SearchOperator接口参考。

使用 searchMeta() 方法创建 $searchMeta 管道阶段,只返回 Atlas 全文搜索查询结果的元数据部分。

提示

仅适用于MongoDB Atlas v4.4.11 及更高版本

此聚合管道操作符符仅适用于运行v4.4.11 及更高版本的MongoDB Atlas集群。有关版本可用性的详细列表,请参阅 $searchMeta 上的MongoDB Atlas文档。

以下示例显示了MongoDB 搜索聚合阶段的 count 元数据:

Aggregates.searchMeta( SearchOperator.near(1985, 2, SearchPath.fieldPath(Movie::year.name)), SearchOptions.searchOptions().index("year"))

通过 searchMeta() API文档了解详情。