I want to create a dynamic mongodb query which insert each part of it's aggregation if the condition is true else don't inject that part.
For example I want to check if the time is between 1AM till 8AM If yes then pass in the defined array to the mongodb query else pass nothing.
if ($this->Not_in_1_8 == true) {
$this->N_IN_1_8 = array('dont_show_between_1_n_8' => array('$ne' => true));
}else {
$this->N_IN_1_8 = null;
}
$MidnightCheck = $this->N_IN_1_8;
$this->campaign = Bcamp::raw(function ($collection) use ($seat_category_list, $banner_size, $seat_filter_list, $gold_network, $MidnightCheck) {
return $collection->aggregate([
[
'$match' => [
'$and' => [
["targets.cats" => [
'$in' => $seat_category_list
]
],
['banners.' . $banner_size => [
'$exists' => true
]
],
['href' => [
'$nin' => $seat_filter_list
]
],
['targets.gold_network' => [
'$eq' => $gold_network
]
],
['status' => [
'$ne' => "Low_Budget"
]
],
['daily_budget_status' => [
'$ne' => "Low_Budget"
]
],
$MidnightCheck
]
]
],
[
'$project' => [
'ab' => [
'$cmp' => [
'$budget', '$click_cost'
]
]
]
],
[
'$match' => [
'ab' => [
'$lt' => 1
]
]
]
]);
});
But In this example It will inject null into query and makes it wrong and I catch error : bad query: BadValue: $or/$and/$nor entries need to be full objects
I have changed it to $this->N_IN_1_8 = '';
still no success.
All I need a neutral variable or condition to pass in which does not affect on query if the condition if false. Any Idea?
FYI : I'm using Laravel 5.3 framework with jenssegers/laravel-mongodb package for working with mongodb
Prefering to keep the code structure as is i.e. when a pre-built array is not used in the condition code, you may keep $MidnightCheck
as null
and wrap the array with array_filter
:
return $collection->aggregate([
[
'$match' => [
'$and' => array_filter([
["targets.cats" => ['$in' => $seat_category_list]],
['banners.' . $banner_size => ['$exists' => true]],
['href' => ['$nin' => $seat_filter_list]],
['targets.gold_network' => ['$eq' => $gold_network]],
['status' => ['$ne' => "Low_Budget"]],
['daily_budget_status' => ['$ne' => "Low_Budget"]],
$MidnightCheck
])
]
// ...
Calling array_filter
without a second argument will filter out all false values from the array, causing the unwanted $MidnightCheck
will be gone.
What I think might be clearer would be to pre-prepare the conditions in the callback:
$conditions = [
["targets.cats" => ['$in' => $seat_category_list]],
['banners.' . $banner_size => ['$exists' => true]],
['href' => ['$nin' => $seat_filter_list]],
['targets.gold_network' => ['$eq' => $gold_network]],
['status' => ['$ne' => "Low_Budget"]],
['daily_budget_status' => ['$ne' => "Low_Budget"]],
];
if ($MidnighCheck) {
$conditions[] = $MidnightCheck;
}
return $collection->aggregate([
['$match' => [ '$and' => $conditions ],]
])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With