Docs 菜单
Docs 主页
/ / /
Mongoid
/

聚合管道 (Aggregation Pipeline)

在此页面上

  • 基本用法
  • 跨多个集合查询
  • Builder DSL
  • GROUP
  • 项目
  • Unwind

Mongoid 公开 MongoDB 的聚合管道,该管道用于构造进程和返回结果的操作流。 聚合管道是已弃用的 map/reduce框架功能的超集。

聚合管道可用于同时涉及多个引用关联的查询:

class Band
include Mongoid::Document
has_many :tours
has_many :awards
field :name, type: String
end
class Tour
include Mongoid::Document
belongs_to :band
field :year, type: Integer
end
class Award
include Mongoid::Document
belongs_to :band
field :name, type: String
end

要检索自2000以来巡回演出并至少获得一项奖项的乐队,可以执行以下操作:

band_ids = Band.collection.aggregate([
{ '$lookup' => {
from: 'tours',
localField: '_id',
foreignField: 'band_id',
as: 'tours',
} },
{ '$lookup' => {
from: 'awards',
localField: '_id',
foreignField: 'band_id',
as: 'awards',
} },
{ '$match' => {
'tours.year' => {'$gte' => 2000},
'awards._id' => {'$exists' => true},
} },
{'$project' => {_id: 1}},
])
bands = Band.find(band_ids.to_a)

请注意,聚合管道是由MongoDB的Ruby驾驶员而不是 Mongoid 实施的,因此会返回原始 BSON::Document对象,而不是Mongoid::Document模型实例。 上述示例仅_id字段,该字段随后用于加载完整模型。 另一种方法是不执行此类投影并使用原始字段,这样就无需在第二个查询(可能很大)中将文档ID 列表发送到 Mongoid。

Mongoid 为使用高级 DSL 构建聚合管道本身提供有限支持。 支持以下聚合管道操作符:

  • $group

  • $project

  • $unwind

要构建管道,请在Criteria实例上调用相应的聚合管道方法。 聚合管道操作将添加到Criteria实例的pipeline属性中。 要执行管道,请将pipeline属性值传递给Collection#aggragegate方法。

例如,给定以下模型:

class Tour
include Mongoid::Document
embeds_many :participants
field :name, type: String
field :states, type: Array
end
class Participant
include Mongoid::Document
embedded_in :tour
field :name, type: String
end

我们可以找出参与者访问了哪些状态:

criteria = Tour.where('participants.name' => 'Serenity',).
unwind(:states).
group(_id: 'states', :states.add_to_set => '$states').
project(_id: 0, states: 1)
pp criteria.pipeline
# => [{"$match"=>{"participants.name"=>"Serenity"}},
# {"$unwind"=>"$states"},
# {"$group"=>{"_id"=>"states", "states"=>{"$addToSet"=>"$states"}}},
# {"$project"=>{"_id"=>0, "states"=>1}}]
Tour.collection.aggregate(criteria.pipeline).to_a

group方法添加一个$ 群组聚合管道阶段

字段表达式支持Mongoid 符号操作符语法:

criteria = Tour.all.group(_id: 'states', :states.add_to_set => '$states')
criteria.pipeline
# => [{"$group"=>{"_id"=>"states", "states"=>{"$addToSet"=>"$states"}}}]

或者,可以使用标准MongoDB聚合管道语法:

criteria = Tour.all.group(_id: 'states', states: {'$addToSet' => '$states'})

project方法添加一个$ 项目聚合管道阶段

参数应该是指定投影的哈希:

criteria = Tour.all.project(_id: 0, states: 1)
criteria.pipeline
# => [{"$project"=>{"_id"=>0, "states"=>1}}]

unwind方法添加$unwind聚合管道阶段

参数可以是字段名称(可指定为符号或string )、哈希或 BSON::Document实例:

criteria = Tour.all.unwind(:states)
criteria = Tour.all.unwind('states')
criteria.pipeline
# => [{"$unwind"=>"$states"}]
criteria = Tour.all.unwind(path: '$states')
criteria.pipeline
# => [{"$unwind"=>{:path=>"$states"}}]

后退

文本搜索(Text Search)