elasticsearch-php multiple range query not working - php

I am using a client for elasticsearch client for elasticsearch, i am not getting the right result for a multiple range query.
The body that i use for querying:
{
"index":"locations",
"type":"portugal",
"body":{
"aggs":{
"unique":{
"aggs":{
"documents":{
"top_hits":{
"size":50
}
}
},
"terms":{
"field":"cp3"
}
}
},
"query":{
"filtered":{
"filter":{
"bool":{
"must":{
"range":{
"latitude":{
"gte":41.1373667,
"lte":41.1373767
},
"longitude":{
"gte":-8.631723,
"lte":-8.631713
}
}
}
}
}
}
}
}
}
the result:
{
"took":2,
"timed_out":false,
"_shards":{
"total":5,
"successful":5,
"failed":0
},
"hits":{
"total":1,
"max_score":1,
"hits":[
{
"_index":"locations",
"_type":"portugal",
"_id":"AVTJ4I0g_vwSgXBDKO-W",
"_score":1,
"_source":{
"id":222956,
"latitude":41.0383217,
"longitude":-8.6317147
}
}
]
},
"aggregations":{
"unique":{
"doc_count_error_upper_bound":0,
"sum_other_doc_count":0,
"buckets":[
{
"key":199,
"doc_count":1,
"documents":{
"hits":{
"total":1,
"max_score":1,
"hits":[
{
"_index":"locations",
"_type":"portugal",
"_id":"AVTJ4I0g_vwSgXBDKO-W",
"_score":1,
"_source":{
"id":222956,
"latitude":41.0383217,
"longitude":-8.6317147
}
}
]
}
}
}
]
}
}
}
as you can see the result's latitude is not inside the latitude range i gave it.
Using the Head plugin from elasticsearch to test:
my query:
{
"query":{
"bool":{
"must":[
{
"range":{
"latitude":{
"gte":"41.1363671",
"lte":"41.1363771"
}
}
},
{
"range":{
"longitude":{
"gt":"-8.6318828",
"lte":"-8.6318728"
}
}
}
],
"must_not":[
],
"should":[
]
}
},
"from":0,
"size":10,
"sort":[
],
"aggs":{
}
}
The result:
(empty), there is no records in this range.
Edit:
added the mapping for my index:
{
"locations":{
"aliases":{
},
"mappings":{
"portugal":{
"properties":{
"cp3":{
"type":"long"
},
"cp4":{
"type":"long"
},
"cpalf":{
"type":"string"
},
"id":{
"type":"long"
},
"latitude":{
"type":"double"
},
"localidade":{
"type":"string"
},
"longitude":{
"type":"double"
}
}
}
},
"settings":{
"index":{
"creation_date":"1463675755006",
"number_of_shards":"5",
"number_of_replicas":"1",
"uuid":"C9OO0ig_QyeigqSufK8_dA",
"version":{
"created":"2030199"
}
}
},
"warmers":{
}
}
}

Test with the following query :
{
"query":{
"bool":{
"must":[
{
"range":{
"latitude":{
"gte": 41.1363671,
"lte": 41.1363771
}
}
},
{
"range":{
"longitude":{
"gt": -8.6318828,
"lte": -8.6318728
}
}
}
],
"must_not":[
],
"should":[
]
}
},
"from":0,
"size":10,
"sort":[
],
"aggs":{
}
}
As longitude and latitude fields are double type the should be compare with double, but you have compared with string.

Related

Elastic search doesn't find document with "-" in it

I have a query in ES:
POST <index>/_search
{
"_source":[
<list_of_fields_to_return>
],
"size":"6",
"from":"0",
"min_score": 10,
"query":{
"function_score":{
"functions":[
{
"field_value_factor":{
"field":"product.sales_count",
"missing":0,
"modifier":"log1p"
}
},
{
"field_value_factor":{
"field":"product.image_count",
"missing":0,
"modifier":"log1p"
}
},
{
"field_value_factor":{
"field":"featureCount",
"missing":0,
"modifier":"log1p"
}
},
{
"field_value_factor":{
"field":"<field>",
"missing":0,
"modifier":"none",
"factor":5
}
},
{
"field_value_factor":{
"field":"<field>",
"missing":0,
"modifier":"none",
"factor":3
}
},
{
"field_value_factor":{
"field":"<field>",
"missing":0,
"modifier":"none",
"factor":2
}
},
{
"field_value_factor":{
"field":"<field>",
"missing":0,
"modifier":"none",
"factor":2
}
},
{
"field_value_factor":{
"field":"<field>",
"missing":0,
"modifier":"none",
"factor":1
}
}
],
"score_mode":"sum",
"query":{
"bool":{
"filter":[
{
"term":{
"product.is_visible":true
}
}
],
"should":[
{
"query_string":{
"fields":[
<field>
],
"query":"ALV3002688-SET~1"
}
},
{
"query_string":{
"fields":[
"<field>"
],
"query":"ALV3002688-SET",
"boost":"2.0"
}
},
{
"query_string":{
"fields":[
"product.ref"
],
"query":"*ALV3002688-SET*", <---- PROBLEM WITH "-" sign
"boost": 10
}
}
]
}
}
}
},
"aggs":{
"by_categories":{
"terms":{
"field":"<field>"
}
}
}
}
If i strip the "-SET", it matches perfectly, can't wildcard search for "-"? For now, it just returns 0 matching documents. I could do something like, strip "-" and replace it with whitespace but then It gives me all documents for example "something\SET".
Also, If I remove the "*" sign it maches perfectly.
What am I missing?

How to make dynamic elastic search query based on my given input values in Elastic Search

I have written elastic search query in static values, now i want to make as a dynamic like i have input fields, based on the input values i have to make my dynamic elastic search query. how can i do it? any one please update my answer.
INPUT
{
"userID" : "USER1",
"groupID" : "5b278f8856db693c457b4697",
"contentType " : "question",
"contentID" : "5",
"contentFlow": [
{
"contentId": "123",
"contentType": "topic"
},
{
"contentId": "456",
"contentType": "concept"
},
{
"contentId": "100",
"contentType": "sdl"
}
]
}
STATIC QUERY
{
"size":999,
"query":{
"bool":{
"must":[
{
"term":{
"userId":"USER1"
}
},
{
"term":{
"contentId":"5"
}
},
{
"bool":{
"must":[
{
"term":{
"contentPath.contentType":"topic"
}
},
{
"term":{
"contentPath.contentId":"123"
}
}
]
}
},
{
"bool":{
"must":[
{
"term":{
"contentPath.contentType":"concept"
}
},
{
"term":{
"contentPath.contentId":"456"
}
}
]
}
},
{
"bool":{
"must":[
{
"term":{
"contentPath.contentType":"sdl"
}
},
{
"term":{
"contentPath.contentId":"100"
}
}
]
}
}
]
}
}
}
I am new to learning elastic search, kindly help me out on this problem

Get nested JSON values [PHP]

I am trying to get some values from a nested JSON, but for some reason I am not getitng the values of the keys. This is my JSON
$data =
{
"currency":"USD",
"results":[
{
"itineraries":[
{
"outbound":{
"duration":"07:10",
"flights":[
{
"departs_at":"2018-09-25T22:50",
"arrives_at":"2018-09-26T11:00",
"origin":{
"airport":"EWR"
},
"destination":{
"airport":"STN"
},
"marketing_airline":"H1",
"operating_airline":"PF",
"flight_number":"1930",
"aircraft":"32S",
"booking_info":{
"travel_class":"ECONOMY",
"booking_code":"T",
"seats_remaining":9
}
}
]
},
"inbound":{
"duration":"08:25",
"flights":[
{
"departs_at":"2018-09-27T17:55",
"arrives_at":"2018-09-27T21:20",
"origin":{
"airport":"STN"
},
"destination":{
"airport":"EWR"
},
"marketing_airline":"H1",
"operating_airline":"PF",
"flight_number":"1929",
"aircraft":"32S",
"booking_info":{
"travel_class":"ECONOMY",
"booking_code":"T",
"seats_remaining":9
}
}
]
}
}
],
"fare":{
"total_price":"538.39",
"price_per_adult":{
"total_fare":"538.39",
"tax":"237.39"
},
"restrictions":{
"refundable":false,
"change_penalties":true
}
}
},
{
"itineraries":[
{
"outbound":{
"duration":"10:30",
"flights":[
{
"departs_at":"2018-09-25T18:55",
"arrives_at":"2018-09-26T04:55",
"origin":{
"airport":"EWR",
"terminal":"B"
},
"destination":{
"airport":"KEF"
},
"marketing_airline":"WW",
"operating_airline":"WW",
"flight_number":"104",
"aircraft":"321",
"booking_info":{
"travel_class":"ECONOMY",
"booking_code":"X",
"seats_remaining":8
}
},
{
"departs_at":"2018-09-26T06:10",
"arrives_at":"2018-09-26T10:25",
"origin":{
"airport":"KEF"
},
"destination":{
"airport":"LGW",
"terminal":"S"
},
"marketing_airline":"WW",
"operating_airline":"WW",
"flight_number":"810",
"aircraft":"321",
"booking_info":{
"travel_class":"ECONOMY",
"booking_code":"X",
"seats_remaining":9
}
}
]
},
"inbound":{
"duration":"11:05",
"flights":[
{
"departs_at":"2018-09-27T17:20",
"arrives_at":"2018-09-27T19:30",
"origin":{
"airport":"STN"
},
"destination":{
"airport":"KEF"
},
"marketing_airline":"WW",
"operating_airline":"WW",
"flight_number":"827",
"aircraft":"321",
"booking_info":{
"travel_class":"ECONOMY",
"booking_code":"E",
"seats_remaining":9
}
},
{
"departs_at":"2018-09-27T21:10",
"arrives_at":"2018-09-27T23:25",
"origin":{
"airport":"KEF"
},
"destination":{
"airport":"JFK",
"terminal":"1"
},
"marketing_airline":"WW",
"operating_airline":"WW",
"flight_number":"109",
"aircraft":"321",
"booking_info":{
"travel_class":"ECONOMY",
"booking_code":"E",
"seats_remaining":9
}
}
]
}
}
],
"fare":{
"total_price":"544.61",
"price_per_adult":{
"total_fare":"544.61",
"tax":"353.61"
},
"restrictions":{
"refundable":false,
"change_penalties":true
}
}
}
]
}
I am trying to foreach trough the JSON and get the value from some of the keys like this
$arr = json_decode($data,true);
foreach($arr['results'] as $data) {
echo "duration: ".$data['itineraries']['outbound']['duration'].PHP_EOL.
"origin: ".$data['itineraries']['outbound']['flights']['origin'].PHP_EOL; //etc
}
However, I am not getting any errors while executing it, but I am not getting the values from the keys either.
I am trying get the values for the duration and origin keys. Any idea what I am doing wrong?
Just found my mistake. I forgot the [0]. So this fixed it.
foreach($arr['results'] as $data) {
echo "duration: ".$data['itineraries'][0]['outbound']['duration'].PHP_EOL.
"origin: ".$data['itineraries'][0]['outbound']['flights'][0]['origin']['airport'].PHP_EOL; //etc
}
Some parsed elements are within an array. And therefore you must add [0] on some spots.
This will work:
foreach ($arr['results'] as $data) {
echo "duration: " . $data['itineraries'][0]['outbound']['duration'] . PHP_EOL .
"origin: " . $data['itineraries'][0]['outbound']['flights'][0]['origin']['airport'] . PHP_EOL; //etc
}
Output:
duration: 07:10
origin: EWR
duration: 10:30
origin: EWR

Shifting specific index's in array to front based on value inside

I have the following array.
{
"flow":[
{
"tasks":[
{ "id":"1", "uid":"bryan" },
{ "id":"2", "uid":"eric" }
]
},
{
"tasks":[
{ "id":"1", "uid":"bryan" },
{ "id":"2", "uid":"eric" }
]
},
{
"tasks":[
{ "id":"1", "uid":"bryan" },
{ "id":"2", "uid":"eric" }
]
},
{
"tasks":[
{ "id":"1", "uid":"bryan" },
{ "id":"2", "uid":"eric" },
{ "id":"3", "uid":"eric" },
{ "id":"4", "uid":"bryan" }
]
}
]
}
Let's say I am eric. If I am eric, I am trying to move all items with the uid of eric to the front of the tasks array.
So that the array would end looking like this:
{
"flow":[
{
"tasks":[
{ "id":"2", "uid":"eric" },
{ "id":"1", "uid":"bryan" }
]
},
{
"tasks":[
{ "id":"2", "uid":"eric" },
{ "id":"1", "uid":"bryan" }
]
},
{
"tasks":[
{ "id":"2", "uid":"eric" },
{ "id":"1", "uid":"bryan" }
]
},
{
"tasks":[
{ "id":"2", "uid":"eric" },
{ "id":"3", "uid":"eric" },
{ "id":"1", "uid":"bryan" },
{ "id":"4", "uid":"bryan" }
]
}
]
}
I've attempted to make a function to do it, but for some reason it's not working the way I intended it to. Does anyone know what I'm doing wrong?
function reorder_flow($flow, $uid)
{
foreach($flow as &$step)
{
//step is the array with tasks
$tasks = $step['tasks'];
$new_tasks = array();
foreach($tasks as $key => $t)
{
if($t['uid'] == $uid)
{
$new_tasks = $new_tasks + $t;
unset($tasks[$key]);
}
}
$step['tasks'] = $new_tasks + $step['tasks'];
}
return $flow;
}
This is a traversal/sorting problem.
$json = <<<JSON
{
"flow":[
{
"tasks":[
{ "id":"1", "uid":"bryan" },
{ "id":"2", "uid":"eric" }
]
},
{
"tasks":[
{ "id":"1", "uid":"bryan" },
{ "id":"2", "uid":"eric" }
]
},
{
"tasks":[
{ "id":"1", "uid":"bryan" },
{ "id":"2", "uid":"eric" }
]
},
{
"tasks":[
{ "id":"1", "uid":"bryan" },
{ "id":"2", "uid":"eric" },
{ "id":"3", "uid":"eric" },
{ "id":"4", "uid":"bryan" }
]
}
]
}
JSON;
$flow = json_decode($json, true);
array_walk($flow['flow'], function(&$flowItem, $key){
usort($flowItem['tasks'], function($a, $b){
$aIsMatch = $a['uid'] === 'eric';
$bIsMatch = $b['uid'] === 'eric';
if ($aIsMatch && $bIsMatch) {
return 0;
}
if ($aIsMatch) {
return -1;
}
if ($bIsMatch) {
return 1;
}
// Fallback sorting criteria - you could use something else or just return 0
return strcasecmp($a['uid'], $b['uid']);
});
});
echo json_encode($flow, JSON_PRETTY_PRINT);
Please try this:
function sortByUID(&$array, $uid) {
array_walk ($array, function($obj) use($uid) {
uasort($obj->tasks, function($a, $b) use($uid) {
return $a->uid == $uid ? -1 : 1;
});
});
}
sortByUID($data->flow, 'eric');
Demo: https://3v4l.org/mOhDX
I hope this will help.
notes:
+ does not work with arrays in that way
json_decode should have the second parameter set to true to get nested arrays
then try this in the foreach:
//step is the array with tasks
$new_tasks=array();
foreach($step['tasks'] as $t){
if($t['uid'] == $uid){
array_unshift($new_tasks,$t);
} else {
array_push($new_tasks,$t);
}
}
$step['tasks'] = $new_tasks;

Elasticsearch multiple queries

i would like to get distinct ip's for example today and where campaigne="2"
in sql:
select distinct ip
from test
where timestamp >= "2016-01-16" ... AND
fk_campaign_id = "2";
this works but json validator outputs "Duplicate key, names should be unique."
{
"size":0,
"aggs":{
"distinct_ip":{
"cardinality":{
"field":"ip"
}
}
},
"query":{
"range":{
"timestamp":{
"gte":"2016-01-16T00:00:00",
"lt":"2016-01-17T00:00:00"
}
}
},
"query":{
"match":{
"fk_campaign_id":"2"
}
}
}
But if i try to build this query in php, var_dump($params) returns me back json only with one "query", may be because of Duplicate key???
{
"size":0,
"aggs":{
"distinct_ip":{
"cardinality":{
"field":"ip"
}
}
},
part with range is not here?!?!?
"query":{
"match":{
"fk_campaign_id":"2"
}
}
}
Thanks in advance.
In your json query is a duplicate key. You need to use bool query whenever you have multiple conditions. since you have AND condition you need to use must clause. This is the right syntax
{
"query": {
"bool": {
"must": [
{
"range": {
"timestamp": {
"gte": "2016-01-16T00:00:00",
"lt": "2016-01-17T00:00:00"
}
}
},
{
"match": {
"fk_campaign_id": "2"
}
}
]
}
},
"size": 0,
"aggs": {
"distinct_ip": {
"cardinality": {
"field": "ip"
}
}
}
}
Hope this helps!

Categories