聚合
该聚合类提供静态工厂方法,用于构建聚合管道阶段。每个方法都返回一个Bson
类型的实例,该实例可以进一步传递给MongoCollection.aggregate()
方法。Bson
类型,它反过来可以传递给MongoCollection.aggregate()
方法。
您可以将Aggregates
类的静态方法导入,如下面的代码所示
import org.mongodb.scala.model.Aggregates._
本指南中的示例假定此静态导入。
匹配
$match
管道阶段将所有匹配指定过滤器的文档传递到下一个阶段。尽管过滤器可以是实现Bson
接口的任何类的实例,但使用来自过滤器类的方
法更方便。
以下示例创建了一个管道阶段,匹配所有作者字段值为“Dave”的文档。
`match`(equal("author", "Dave"))
注意
由于在Scala中“match”是一个保留字,必须使用反引号进行转义,你可能更喜欢使用filter()
别名。
filter(equal("author", "Dave"))
项目
$project
管道阶段将所有文档的投影字段传递到下一个阶段。虽然投影可以是实现Bson
的任何类的实例,但使用Projections类的方
以下示例创建了一个管道阶段,排除_id
字段,但包括title
和author
字段。
project(fields(include("title", "author"), excludeId()))
计算字段
$project
阶段还可以投影计算字段。
以下示例将qty
字段投影到名为quantity
的新字段中。换句话说,它重命名了该字段
project(computed("quantity", "$qty"))
示例
$sample
管道阶段从输入文档中随机选择 N
个文档。以下示例使用 sample()
方法从集合中随机选择 5
个文档
sample(5)
排序
$sort
管道阶段将所有文档按指定的排序标准排序后传递到下一个阶段。尽管排序标准可以是实现 Bson
的任何类的实例,但使用 Sorts 类的方法更为方便。
以下示例创建了一个管道阶段,该阶段根据 age
字段的值按降序排序,然后根据 posts
字段的值按升序排序
sort(orderBy(descending("age"), ascending("posts")))
跳过
管道阶段的 $skip
跳过通过该阶段的前指定数量的文档,并将剩余的文档传递到下一阶段。
以下示例跳过前 5
个文档
skip(5)
限制
管道阶段的 $limit
限制了传递到下一阶段的文档数量。
以下示例将文档数量限制为 10
limit(10)
查找
管道阶段的 $lookup
与另一个集合执行左外连接,以从连接的集合中筛选文档进行处理。
以下示例在 fromCollection
集合上执行左外连接,将 local
字段与 from
字段连接,并在 joinedOutput
字段输出
lookup("fromCollection", "local", "from", "joinedOutput")
分组
管道阶段的 $group
按某些指定的表达式对文档进行分组,并将每个不同分组的一个文档输出到下一阶段。一个分组包括一个 _id
,它指定了分组的表达式,以及零个或多个累加器,这些累加器为每个分组进行评估。
为了简化累加器的表达式,驱动程序包含一个 Accumulators
单例对象,为每个支持的累加器提供了工厂方法。
以下示例通过 customerId
字段的值对文档进行分组,并为每个分组累加数量字段的值到 totalQuantity
和 averageQuantity
字段。
group("$customerId", sum("totalQuantity", "$quantity"), avg("averageQuantity", "$quantity"))
展开
$unwind
管道阶段将输入文档中的数组字段解构,输出每个元素对应的文档。
以下示例为每个文档输出 sizes
数组中的每个元素对应的文档。
unwind("$sizes")
以下示例还包括任何缺少或为空值 sizes
字段或 sizes
列表为空的文档。
unwind("$sizes", UnwindOptions().preserveNullAndEmptyArrays(true))
以下示例展开 sizes
数组,并将数组索引输出到 position
字段。
unwind("$sizes", UnwindOptions().includeArrayIndex("$position"))
设置窗口字段
$setWindowFields
管道阶段允许使用窗口操作符。此阶段将输入文档分区的方式与 $group
管道阶段类似,可选地对它们进行排序,通过计算每个函数指定的窗口上的窗口函数来计算文档中的字段,并输出文档。窗口是分区的子集。
与 $group
管道阶段的重要区别是,属于同一分区或窗口的文档不会被折叠为单个文档。
驱动程序包含具有支持窗口操作符工厂方法的 WindowedComputations
单例对象。
以下示例计算过去一个月每个地区从更精细的测量值中得出的累计降雨量和平均温度。
val pastMonth: Window = Windows.timeRange(-1, MongoTimeUnit.MONTH, Windows.Bound.CURRENT) setWindowFields(Some("$localityId"), Some(Sorts.ascending("measurementDateTime")), WindowedComputations.sum("monthlyRainfall", "$rainfall", Some(pastMonth)), WindowedComputations.avg("monthlyAvgTemp", "$temperature", Some(pastMonth)))
组装管道
管道操作符通常组合成一个列表,并传递给 aggregate()
方法的一个 MongoCollection
collection.aggregate(List(filter(equal("author", "Dave")), group("$customerId", sum("totalQuantity", "$quantity"), avg("averageQuantity", "$quantity")), out("authors")))