Монгоидная агрегация с условиями - PullRequest
0 голосов
/ 26 марта 2019

Я использую инфраструктуру агрегации mongoid 6.1.0 в своем проекте Rails 5.Мне нужно добавить конвейер $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? нельзя включить в структуру агрегирования.Есть ли другое альтернативное решение?

Ответы [ 2 ]

1 голос
/ 26 марта 2019

Я не знаю рубина, но, возможно, я понимаю вашу проблему.

Псевдо-код

# 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
  }
])

UPDATE : Как отметил Абузар Раджаби, если условие истинно, мы можем просто добавить $match stage к конвейеру:

pipeline = [
    # stages
];

if condition is true:
  pipeline.push({
      $match: {
          # filter
      }
  });
0 голосов
/ 27 марта 2019

Приведенный выше псевдокод (ответ Кан А) переведен на 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

Iнадеюсь, что это поможет другим, кто увидит эту страницу позже.Кроме того, это решение и код, о котором идет речь, будут примером использования платформы агрегации MongoDB в проекте Rails или Ruby.

...