具有条件的 Mongoid 聚合
Mongoid aggregation with conditions
我在 Rails 5 项目中使用 mongoid 6.1.0 聚合框架。如果搜索字段(文本或 select 字段)的值不为空,我需要添加一个 $match
管道。否则,它应该被忽略并且不过滤结果。类似于:
@messages = Message.collection.aggregate([
{ '$match' => {'month': {'$gte' => @fr_mnth, '$lte' => @to_mnth}}},
{ '$group' => {'_id': '$mmsi'} },
{ '$lookup' => {'from': 'ships', 'localField': "_id", 'foreignField': "mmsi", as: "ship"}},
{ '$match' => {"ship.n2": params[:n2] if !params[:n2].blank? }}
]).allow_disk_use(true)
或者更清楚:
if not params[:n2].blank? { '$match' => {"ship.n2": params[:n2] }}
问题是 if !params[:n2].blank?
无法包含在聚合框架中。还有其他替代解决方案吗?
我不知道ruby,但也许我理解你的问题。
伪代码
# DON'T DO SO! SEE UPDATE BELOW
if your_condition is true:
filter = { field: 'some value' }
else:
filter = { # always true condition
$or: [
{ field: { $exists: true } },
{ field: { $exists: false } }
]
}
Message.collection.aggregate([
# ...
{
"$match": filter
}
])
更新:
正如 Aboozar Rajabi 指出的那样,如果条件为真,那么我们可以将 $match
阶段添加到管道中:
pipeline = [
# stages
];
if condition is true:
pipeline.push({
$match: {
# filter
}
});
上面的伪代码(Kan A 的回答)被翻译成 Ruby 和 Mongoid 聚合框架,因为它的语法可能有点混乱,网上有一些 Mongoid 聚合示例:
if not params[:field].blank?
filter = { "db_field_name": params[:field] }
else
filter = {
'$or' => [
{ "db_field_name" => { '$exists' => true } },
{ "db_field_name" => { '$exists' => false } }
]
}
end
希望对以后看到此页面的人有所帮助。此外,此解决方案和问题中的代码将是在 Rails 或 Ruby 项目中使用 MongoDB 聚合框架的示例。
我在 Rails 5 项目中使用 mongoid 6.1.0 聚合框架。如果搜索字段(文本或 select 字段)的值不为空,我需要添加一个 $match
管道。否则,它应该被忽略并且不过滤结果。类似于:
@messages = Message.collection.aggregate([
{ '$match' => {'month': {'$gte' => @fr_mnth, '$lte' => @to_mnth}}},
{ '$group' => {'_id': '$mmsi'} },
{ '$lookup' => {'from': 'ships', 'localField': "_id", 'foreignField': "mmsi", as: "ship"}},
{ '$match' => {"ship.n2": params[:n2] if !params[:n2].blank? }}
]).allow_disk_use(true)
或者更清楚:
if not params[:n2].blank? { '$match' => {"ship.n2": params[:n2] }}
问题是 if !params[:n2].blank?
无法包含在聚合框架中。还有其他替代解决方案吗?
我不知道ruby,但也许我理解你的问题。
伪代码
# DON'T DO SO! SEE UPDATE BELOW
if your_condition is true:
filter = { field: 'some value' }
else:
filter = { # always true condition
$or: [
{ field: { $exists: true } },
{ field: { $exists: false } }
]
}
Message.collection.aggregate([
# ...
{
"$match": filter
}
])
更新:
正如 Aboozar Rajabi 指出的那样,如果条件为真,那么我们可以将 $match
阶段添加到管道中:
pipeline = [
# stages
];
if condition is true:
pipeline.push({
$match: {
# filter
}
});
上面的伪代码(Kan A 的回答)被翻译成 Ruby 和 Mongoid 聚合框架,因为它的语法可能有点混乱,网上有一些 Mongoid 聚合示例:
if not params[:field].blank?
filter = { "db_field_name": params[:field] }
else
filter = {
'$or' => [
{ "db_field_name" => { '$exists' => true } },
{ "db_field_name" => { '$exists' => false } }
]
}
end
希望对以后看到此页面的人有所帮助。此外,此解决方案和问题中的代码将是在 Rails 或 Ruby 项目中使用 MongoDB 聚合框架的示例。