Reputation: 1793
I'm using the mongoid 6.1.0 aggregation framework in my Rails 5 project. I need to add a $match
pipeline if the value of a search field (text or select field) is not empty. Otherwise, it should be ignored and don't filter results. Something like:
@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)
or to be more clear:
if not params[:n2].blank? { '$match' => {"ship.n2": params[:n2] }}
The problem is that if !params[:n2].blank?
cannot be included in the aggregation framework. Is there any other alternative solution?
Upvotes: 0
Views: 529
Reputation: 103
I don't know ruby, but maybe I understand your problem.
Pseudo-code
# 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:
As Aboozar Rajabi noted, if condition is true then we can just add $match
stage to pipeline:
pipeline = [
# stages
];
if condition is true:
pipeline.push({
$match: {
# filter
}
});
Upvotes: 1
Reputation: 1793
The above pseudo-code (Kan A's answer) is translated to Ruby and Mongoid aggregation framework as its syntax might be a bit confusing and there're a few Mongoid aggregation examples online:
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 hope it would help the others who will see this page later. Also, this solution and the code in the question would be an example of using MongoDB aggregation framework in a Rails or Ruby project.
Upvotes: 0