0

我在我的 Rails 5 项目中使用 mongoid 6.1.0 聚合框架。$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?不能包含在聚合框架中。还有其他替代解决方案吗?

4

2 回答 2

1

我不知道红宝石,但也许我理解你的问题。

伪代码

# 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
      }
  });
于 2019-03-26T19:28:41.713 回答
0

上面的伪代码(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 聚合框架的示例。

于 2019-03-27T13:33:15.237 回答