MongoDB or operator for range - php

This is the range Im using :
$Range1=array('$or'=>array(
array( '$gte' => floatval($O_NLA), '$lte' => $N_NLA ),
array( '$gte' => floatval($N_SLA), '$lte' => $O_SLA ))
);
$Range2=array('$or'=>array(
array( '$gte' => floatval($N_SLO), '$lte' => $O_SLO ),
array( '$gte' => floatval($O_NLO), '$lte' => $N_NLO ))
);
A part of my query :
$finder=$reposit->findBy(
array(
'field1' => $Range1,
'field2' => $Range2,
'display'=>1
))->toArray();
"message":"localhost:27017: invalid operator: $or"..... (it's long though)
How can I use $or operator with doctrine without query builder?

findBy([
'$or' => [
['field1' => ['$gte' => floatval($O_NLA), '$lte' => $N_NLA]],
['field1' => ['$gte' => floatval($N_SLA), '$lte' => $O_SLA]],
['field2' => ['$gte' => floatval($N_SLO), '$lte' => $O_SLO]],
['field2' => ['$gte' => floatval($O_NLO), '$lte' => $N_NLO]]
]
, 'display' => 1
])
Or actually:
findBy([
'$and' => [
['$or' => [
['field1' => ['$gte' => floatval($O_NLA), '$lte' => $N_NLA]],
['field1' => ['$gte' => floatval($N_SLA), '$lte' => $O_SLA]],
]],
['$or' => [
['field2' => ['$gte' => floatval($N_SLO), '$lte' => $O_SLO]],
['field2' => ['$gte' => floatval($O_NLO), '$lte' => $N_NLO]]
]]
]
, 'display' => 1
])
To be more precise according to your question.
Since the $or works upon condition which then contains a find() like array.

Related

PHP SOAP Request to Bing Ads API

I'm having a tough time figuring out how to properly code sequenced SOAP requests to the Bing Ads API. Prefer not to use their SDK, which I have used in the past.
The parameters 'Scope', 'Time', 'Filter', and 'Sort' do not affect the result. The entire account keywords are returned instead. For 'Scope', I am using the Adgroups param to select keywords in that Adgroup. Any help is greatly appreciated.
Reference: https://learn.microsoft.com/en-us/advertising/reporting-service/keywordperformancereportrequest?view=bingads-13
WSDL: https://reporting.api.bingads.microsoft.com/Api/Advertiser/Reporting/V13/ReportingService.svc?singleWsdl
$request = [
'ReportRequest' => new SoapVar(
[
'Format' => 'Csv',
'ReportName' => 'Bing Keyword Performance Report',
'ReturnOnlyCompleteData' => false,
'Aggregation' => 'Daily',
'Sort' => array('SortColumn' => 'Clicks','SortOrder' => 'Ascending'),
'Scope' => ['AdGroups' => array(array('AccountId' => $bClientId,
'AdGroupId' => $apiDBIdGroupBing,
'CampaignId' => $apiDBIdCampaignBing,
))],
'Time' => [
'CustomDateRangeStart' =>
array('Day' => $startDay,'Month' => $startMonth,'Year' => $startYear),
'CustomDateRangeEnd' =>
array('Day' => $endDay,'Month' => $endMonth,'Year' => $endYear)
],
'Filter' => ['Keywords' => array($criteriaValue)],
'Columns' => [
"TimePeriod",
"Spend",
"Clicks",
"CurrentMaxCpc",
"Impressions",
"AdGroupName"
]
],
SOAP_ENC_OBJECT,
'KeywordPerformanceReportRequest',
"https://bingads.microsoft.com/Reporting/v13"
)];
Solved:
$request = [
'ReportRequest' => new SoapVar(
[
'Format' => 'Csv',
'ReportName' => 'Bing Keyword Performance Report',
'ReturnOnlyCompleteData' => false,
'Aggregation' => 'Monthly',
'Sort' => array('SortColumn' => 'Clicks','SortOrder' => 'Ascending'),
'Scope' => ['AccountIds' => [$bClientId]],
'MaxRows' => '9000000',
'Time' => ['PredefinedTime' => $reportTimeFrame],
'Columns' => [
"Keyword",
"Spend",
"CampaignId",
"AdGroupId",
"AveragePosition",
"CurrentMaxCpc",
"KeywordId",
"BidMatchType",
"Impressions",
"Clicks",
"TimePeriod",
"QualityScore",
"ExpectedCtr",
"AdRelevance",
"LandingPageExperience",
"CampaignStatus",
"AdGroupStatus",
"KeywordStatus",
"AccountName",
"CampaignName",
"AdGroupName",
"BidStrategyType",
]
],
SOAP_ENC_OBJECT,
'KeywordPerformanceReportRequest',
"https://bingads.microsoft.com/Reporting/v13"
)];
$response = $SoapClient->SubmitGenerateReport($request);

Uncaught exception 'MongoDB\Driver\Exception\RuntimeException' with message 'An object representing an expression must have exactly one field:

I have written like below lines of code
$cursor = $this->collection->aggregate(array(
array(
'$match' => array(
"_id" => new MongoDB\BSON\ObjectID($this->id)
)
),
array(
'$project' => array(
'AllotmentsDetails' => array(
'$filter' => array(
'input' => '$AllotmentsDetails',
'as' => 'allot',
'cond' => array(
'$and' => array(
'$lt' => array('$$allot.ToDate', new MongoDB\BSON\UTCDateTime((new DateTime())->getTimestamp() * 1000)),
'$eq' => array('$$allotment.RoomId', $this->RoomId)
)
)
)
),
)
)
))->toArray();
It is throwing error message " Uncaught exception 'MongoDB\Driver\Exception\RuntimeException' with message 'An object representing an expression must have exactly one field:"
Please help!!!
Just missing array notations and matching up in some wrong places:
$pipeline = array(
array( '$match' => array(
"_id" => new MongoDB\BSON\ObjectID($this->id)
)),
array('$project' => array(
'AllotmentsDetails' => array(
'$filter' => array(
'input' => '$AllotmentsDetails',
'as' => 'allotment',
'cond' => array(
'$and' => array(
array('$lt' => array(
'$$allotment.ToDate',
new MongoDB\BSON\UTCDateTime((new DateTime())->getTimestamp() * 1000)
)),
array('$eq' => array('$$allotment.RoomId', $this->RoomId))
)
)
)
)
))
);
$cursor = $this->collection->aggregate($pipeline)->toArray();
or since we are in a modern world, a bit easier to read:
$pipeline = [
['$match' => [
"_id" => new MongoDB\BSON\ObjectID($this->id)
]],
['$project' => [
'AllotmentsDetails' => [
'$filter' => [
'input' => '$AllotmentsDetails',
'as' => 'allotment',
'cond' => [
'$and' => [
['$lt' => [
'$$allotment.ToDate',
new MongoDB\BSON\UTCDateTime((new DateTime())->getTimestamp() * 1000)
]],
['$eq' => ['$$allotment.RoomId', $this->RoomId] ]
]
]
]
]
]]
];
$cursor = $this->collection->aggregate($pipeline)->toArray();
I suggest a better editor and also to use json_encode() on your data structures in order to check that the generated JSON matches what you see as examples in the documentation.

Add a row to an array

I'm trying to create a function, in order to create an array.
I'm able to create this array :
$result = [ 'data' =>
[0 =>
[
'months' => $months[0],
'years' => $years[0],
'date' => $date[0],
'hr' => $hr[0],
'isms' => $isms[0],
'product' => $product[0],
'exploitation' => $exploitation[0]
],
],
];
And my prob is that i would like to create a function(PHP) in order to add some rows in this array. I would like to have this kind of result :
$result = [ 'data' =>
[0 =>
[
'months' => $months[0],
'years' => $years[0],
'date' => $date[0],
'hr' => $hr[0],
'isms' => $isms[0],
'product' => $product[0],
'exploitation' => $exploitation[0]
],
[
'months' => $months[0],
'years' => $years[0],
'date' => $date[0],
'hr' => $hr[0],
'isms' => $isms[0],
'product' => $product[0],
'exploitation' => $exploitation[0]
]
]
];
But everytime i try to push, it creates a "1=>...."
What can I do ? Could you help me ?
You need to do like below:-
$result['data'][] = [
'months' => $months[0],
'years' => $years[0],
'date' => $date[0],
'hr' => $hr[0],
'isms' => $isms[0],
'product' => $product[0],
'exploitation' => $exploitation[0]
];
Output:-https://eval.in/990308
Your first array should be like this -
$result = [ 'data' =>
[0 =>
[0 =>
[
'months' => $months[0],
'years' => $years[0],
'date' => $date[0],
'hr' => $hr[0],
'isms' => $isms[0],
'product' => $product[0],
'exploitation' => $exploitation[0]
],
],
],
];
Now use below code to add new row to your array -
$row = [
'months' => $months[0],
'years' => $years[0],
'date' => $date[0],
'hr' => $hr[0],
'isms' => $isms[0],
'product' => $product[0],
'exploitation' => $exploitation[0]
];
$result['data'][0][] = $row;
print_r($result);

MongoDB php add tz offset to aggregate query and average output

I know that mongoDB (php-driver) saves the date as ISODate in Milliseconds UTC, so i have to add a offset for my timezone (GMT +2:00) to the aggregate query.
$dateStart = new MongoDB\BSON\UTCDateTime(strtotime("now 00:00:00") * 1000);
$dateEnd = new MongoDB\BSON\UTCDateTime(time() * 1000);
$queryHours = [
['$match' => ['date' => ['$gte' => $dateStart, '$lte' => $dateEnd]]],
['$project' => ['date' => ['$add' => ['$date', 2*60*60000]]]],
['$group' => ['_id' => ['$hour' => '$date'], 'average' => ['$avg' => '$zapi.apiRes.curlHeader.total_time']]],
['$sort' => ['_id' => 1]],
];
The $hour result seems to be correct, but i get no "average" result and i doesn't see my failure since days, staring at the code. :(
Sample Document:
{
"_id" : ObjectId("58e4e3ca135d9e038242b248"),
"date" : ISODate("2017-04-05T12:32:10Z"),
[...]
"zapi" : {
"apiRes" : {
"apiCall" : {
[...]
},
"curlHeader" : {
"url" : "http://api:/api/foo",
"http_code" : 204,
"total_time" : 0.02906399999999998,
[...]
},
}
},
}
I know that mongoDB working on this feature nativ: https://jira.mongodb.org/browse/SERVER-28611.
Thanks and best regards,
lun4tic
You can replace your $project stage with $addFields if you are on 3.4 version.
$queryHours =
[
['$match' => ['date' => ['$gte' => $dateStart, '$lte' => $dateEnd]]],
['$addFields' => ['date' => ['$add' => ['$date', 2*60*60000]]]],
['$group' => ['_id' => ['$hour' => '$date'], 'average' => ['$avg' => '$zapi.apiRes.curlHeader.total_time']]],
['$sort' => ['_id' => 1]],
];
Or
You can simply move the timezone arithmetic from $project stage into $group stage.
['$group' => ['_id' => ['$hour' => [ '$add' => ['$date', 2*60*60000] ] ], 'average' => ['$avg' => '$zapi.apiRes.curlHeader.total_time']]],
Your error should be the project phase. You have to add 'zapi.apiRes.curlHeader.total_time' => 1 so try this:
$queryHours = [
['$match' => ['date' => ['$gte' => $dateStart, '$lte' => $dateEnd]]],
['$project' => ['date' => ['$add' => ['$date', 2*60*60000]], 'zapi.apiRes.curlHeader.total_time' => 1]],
['$group' => ['_id' => ['$hour' => '$date'], 'average' => ['$avg' => '$zapi.apiRes.curlHeader.total_time']]],
['$sort' => ['_id' => 1]],
];

Can’t filter search result

My Elasticsearch query is like that:
array(
'index' => 'myindex',
'type' => 'myindextype',
'from' => 0,
'size' => 500,
'body' => array(
'query' => array(
'filtered' => array(
'filter' => NULL,
'query' => array(
'query_string' => array(
'default_operator' => 'AND',
'query' => 'atm*',
'minimum_should_match' => '80%',
'default_field' => 'index'
)
)
)
)
)
);
Result is like that:
array(
'took' => 6,
'timed_out' => false,
'_shards' => array(
'total' => 5,
'successful' => 5,
'failed' => 0
),
'hits' => array(
'total' => 492,
'max_score' => 1,
'hits' => array(
0 => array(
'_index' => 'myindex',
'_type' => 'myindextype',
'_id' => 'Branch-571',
'_score' => 1,
'_source' => array(
'indexId' => 'Branch-571',
'objId' => '571',
'index' => 'atm Baki CNaxcivanski lisey Baki sheh Zig shossesi Admiral Naximov kuc 1 ',
'type' => 'Branch',
'title' => 'Bakı C.Naxçıvanski lisey'
)
),
.................................................................................................
196 => array(
'_index' => 'myindex',
'_type' => 'myindextype',
'_id' => 'Page-114',
'_score' => 1,
'_source' => array(
'indexId' => 'Page-114',
'objId' => 'Page-114',
'index' => 'atm Baki CNaxcivanski lisey Baki sheh Zig shossesi Admiral Naximov kuc 1 ',
'type' => 'Page',
'title' => 'Kreditlər'
)
)
.................................................................................................
)
)
);
I want to filter result and get results where 'type' => 'Branch' and I change query like that
array(
'index' => 'myindex',
'type' => 'myindextype',
'from' => 0,
'size' => 10,
'body' => array(
'query' => array(
'filtered' => array(
'filter' => array(
'bool' => array(
'must' => array(
'term' => array(
'type' => 'Branch'
)
)
)
),
'query' => array(
'query_string' => array(
'default_operator' => 'AND',
'query' => 'atm*',
'minimum_should_match' => '80%',
'default_field' => 'index'
)
)
)
)
)
);
But this search return nothing.
array(
'took' => 2,
'timed_out' => false,
'_shards' => array(
'total' => 5,
'successful' => 5,
'failed' => 0
),
'hits' => array(
'total' => 0,
'max_score' => NULL,
'hits' => array()
)
);
I think query is right but no idea why it didn't get any result.
Mapping is
array(
'myindex' => array(
'mappings' => array(
'myindextype' => array(
'properties' => array(
'index' => array(
'type' => 'string'
),
'indexId' => array(
'type' => 'string'
),
'objId' => array(
'type' => 'string'
),
'title' => array(
'type' => 'string'
),
'type' => array(
'type' => 'string'
)
)
)
)
)
)
I have find answer myself. The search query must be like that
POST _search
{
"query": {
"bool" : {
"must" : {
"query_string" :{
"query":"atm*",
"default_operator":"AND",
"minimum_should_match":"80%",
"default_field":"index"
}
},
"filter": {
"term": {
"type.keyword": "Branch"
}
}
}
}
}
All is working good now.

Categories