聚合构建器
本页内容
概述
在本指南中,您可以了解如何使用聚合类,该类提供静态工厂方法,用于构建MongoDB Kotlin驱动程序中的聚合管道阶段。
要深入了解聚合,请参阅我们的聚合指南.
本页面的示例假设以下类的导入方法
聚合
过滤器
投影
排序
累积器
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()
本指南中的许多聚合
示例都使用了Atlas样本_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 ){ data class IMDB( val rating: Double ) }
匹配
使用 match()
方法创建一个匹配传入文档与指定查询筛选器的 $match 管道阶段,过滤掉不匹配的文档。
提示
筛选器可以是实现 Bson
的任何类的实例,但与使用 筛选器 类结合使用会更方便。
以下示例创建了一个管道阶段,该阶段匹配所有 movies
集合中 title
字段等于 "肖申克的救赎" 的文档。
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
的任何类的实例,但与使用 排序。
以下示例创建了一个管道阶段,根据 year
字段的值降序排序,然后根据 title
字段的值升序排序。
Aggregates.sort( Sorts.orderBy( Sorts.descending(Movie::year.name), Sorts.ascending(Movie::title.name) ) )
跳过
使用 skip()
方法创建一个 $skip 管道阶段,在将文档传递到下一阶段之前跳过指定数量的文档。
以下示例创建了一个管道阶段,跳过 movies
集合中的前5个文档。
Aggregates.skip(5)
限制
使用$limit 管道阶段来限制传递给下一个阶段的文档数量。
以下示例创建了一个管道阶段,该阶段限制从 movies
集合返回的文档数量为 4
。
Aggregates.limit(4)
查找
使用 lookup()
方法创建一个 $lookup 管道阶段,以在两个集合之间执行连接和未关联的子查询。
左外连接
以下示例创建了一个管道阶段,该阶段在样本 mflix
数据库中的 movies
和 comments
集合之间执行左外连接。
它将
movies
中的_id
字段与comments
中的movie_id
字段连接起来。它将结果输出到
joined_comments
字段。
Aggregates.lookup( "comments", "_id", "movie_id", "joined_comments" )
全连接和非相关子查询
以下示例使用了虚构的 orders
和 warehouses
集合。数据使用以下 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 )
示例创建了一个管道阶段,通过项目以及 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 管道阶段,以按指定表达式对文档进行分组,并为每个不同的分组输出一个文档。
提示
该驱动程序包含具有静态工厂方法的类,这些方法为每个支持的累加器提供。
以下示例创建了一个管道阶段,该阶段按 customerId
字段的值对 orders
集合中的文档进行分组。每个分组将 ordered
字段的值总和和平均值累加到 totalQuantity
和 averageQuantity
字段中。
Aggregates.group("\$${Order::customerId.name}", Accumulators.sum("totalQuantity", "\$${Order::ordered.name}"), Accumulators.avg("averageQuantity", "\$${Order::ordered.name}") )
有关累加器操作符的更多信息,请参阅服务器手册中的累加器部分。
选择-N 累加器
选择-N 累加器是聚合累加操作符,根据特定的排序返回顶部和底部元素。使用以下构建器之一创建聚合累加操作符
提示
仅当运行 MongoDB v5.2 或更高版本时,才能使用这些选择-N 累加器进行聚合操作。
有关可以使用累加器操作符的聚合管道阶段的信息,请参阅服务器手册中的累加器部分。
选择-N 累加器示例使用 sample-mflix
数据库中的 movies
集合中的文档。
MinN
minN()
构建器创建返回分组中具有最低n个值的文档数据的$minN累加器。
提示
$minN
和$bottomN
累加器可以执行类似任务。有关每个累加器的推荐用法,请参阅$minN和$bottomN累加器的比较。
以下示例演示了如何使用minN()
方法返回按year
分组的电影中最低三个imdb.rating
值。
Aggregates.group( "\$${Movie::year.name}", Accumulators.minN( "lowestThreeRatings", "\$${Movie::imdb.name}.${Movie.IMDB::rating.name}", 3 ) )
有关更多信息,请参阅minN() API文档。
MaxN
maxN()
累加器返回分组中具有最高n个值的文档数据。
以下示例演示了如何使用maxN()
方法,根据year
分组,返回电影中评分最高的两个imdb.rating
值。
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()
方法,根据它们进入阶段的顺序,按year
分组,返回前两个电影title
值。
Aggregates.group( "\$${Movie::year.name}", Accumulators.firstN( "firstTwoMovies", "\$${Movie::title.name}", 2 ) )
有关更多信息,请参阅firstN() API文档。
最后N
lastN()
累加器返回指定排序顺序下每个分组中最后 n
个文档的数据。
以下示例演示了如何使用 lastN()
方法来显示基于它们进入阶段的顺序,按 year
分组的最后三个电影 title
值。
Aggregates.group( "\$${Movie::year.name}", Accumulators.lastN( "lastThreeMovies", "\$${Movie::title.name}", 3 ) )
有关更多信息,请参阅lastN() API 文档。
顶部
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
值返回最长三部电影的总时长 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
累加器 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}"), ) )
请参阅bottomN() 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_ratings
集合中,如果 year
和 title
都匹配,则替换文档,否则插入文档
Aggregates.merge( MongoNamespace("aggregation", "movie_ratings"), MergeOptions().uniqueIdentifier(listOf("year", "title")) .whenMatched(MergeOptions.WhenMatched.REPLACE) .whenNotMatched(MergeOptions.WhenNotMatched.INSERT) )
GraphLookup
使用 graphLookup()
方法创建一个 $graphLookup 管道阶段,在指定的集合中执行递归搜索,以将一个文档中指定的字段与另一个文档中指定的字段匹配。
以下示例使用 contacts
集合。数据使用以下 Kotlin 数据类进行建模
data class Users( val name: String, val friends: List<String>?, val hobbies: List<String>? )
该示例计算《contact》集合中用户的报告图,递归地将《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》阶段与一个《$group》阶段和一个带有《$sum》累加器的《$sort》阶段相同。
[ { "$group": { "_id": <expression to group on>, "count": { "$sum": 1 } } }, { "$sort": { "count": -1 } } ]
以下示例按《genres》字段对《movies》集合中的文档进行分组,并计算每个不同值的出现次数。
Aggregates.sortByCount("\$${Movie::genres.name}"),
替换根
使用《replaceRoot()`》方法创建一个$replaceRoot管道阶段,用指定的文档替换每个输入文档。
以下示例使用一个虚构的 books
集合,其中包含以下 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
集合的输入文档中
Aggregates.addFields( Field("watched", false), Field("type", "movie") )
计数
使用 count()
方法创建一个 $count 管道阶段,该阶段计算进入该阶段的文档数量,并将该值分配给指定的字段名称。如果您未指定字段,则 count()
将字段名称默认为 "count"。
提示
$count
阶段是
{ "$group":{ "_id": 0, "count": { "$sum" : 1 } } }
以下示例创建一个管道阶段,该阶段在名为 "total" 的字段中输出传入文档的计数
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()
方法创建一个 $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
。
提示
该驱动程序包含具有静态工厂方法的类,这些方法为每个支持的累加器提供。
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 管道阶段,允许使用窗口操作符在集合中指定的文档范围内执行操作。
以下示例使用一个虚构的 weather
集合,使用以下 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 sample weather dataset,包含类似的 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( 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, ... }}
有关更多信息,请参阅densify包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( 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)
请参阅fill包API文档以获取更多信息。
Atlas全文搜索
使用search()
方法创建一个$search管道阶段,指定对一个或多个字段的全文搜索。
提示
仅适用于MongoDB v4.2及以上版本的Atlas
此聚合管道运算符仅适用于托管在MongoDB Atlas集群上的集合,这些集群运行v4.2或更高版本,并受Atlas搜索索引保护。从Atlas Search文档中了解更多有关所需设置和此运算符的功能信息。
以下示例创建了一个管道阶段,该阶段在movies
集合的title
字段中搜索包含单词"Future"的文本。
Aggregates.search( SearchOperator.text( SearchPath.fieldPath(Movie::title.name), "Future" ), SearchOptions.searchOptions().index("title") )
了解有关构建器的更多信息,请参阅搜索包API文档。
Atlas搜索元数据
使用searchMeta()
方法创建一个$searchMeta管道阶段,该阶段仅返回Atlas全文搜索查询的结果元数据部分。
提示
仅在MongoDB v4.4.11及更高版本上的Atlas上可用
此聚合管道运算符仅适用于运行v4.4.11及更高版本的MongoDB Atlas集群。有关版本可用性的详细列表,请参阅MongoDB Atlas文档中的$searchMeta.
以下示例显示了Atlas搜索聚合阶段的count
元数据
Aggregates.searchMeta( SearchOperator.near(1985, 2, SearchPath.fieldPath(Movie::year.name)), SearchOptions.searchOptions().index("year") )
了解有关此辅助器的更多信息,请参阅 searchMeta() API 文档。
Atlas 向量搜索
重要
有关支持此功能的 MongoDB Atlas 版本信息,请参阅 Atlas 文档中的 限制。
使用 vectorSearch()
方法创建一个 $vectorSearch 管道阶段,指定一个 语义搜索。语义搜索是一种能够定位意义相似的片段信息的一种搜索类型。
要在集合上执行聚合时使用此功能,您必须创建一个向量搜索索引并索引您的向量嵌入。有关如何在 MongoDB Atlas 中设置搜索索引的说明,请参阅 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个文档
筛选年份值至少为
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文档。