geo_point for location field within array field - php

I have data in elasticsearch like this
"id": "edff12sd3"
"main_array": [
{
"id": "2308",
"name": "Grey Area",
"location": {
"lat": 28.5696577,
"lon": 77.3229933
}
}
,
{
"id": "2274",
"name": "Tribute to The Beatles by Atul Ahuja- Live Music",
"location": {
"lat": 29.5696577,
"lon": 77.3229933
}
}
Now i want to set geo_point for location field. I have tried in this way
{
"mappings": {
"search_data": {
"properties": {
"main_array.location": {
"type": "geo_point"
}
}
}
}
}
but it throws me error
"type": "mapper_parsing_exception",
"reason": "Field name [main_array.location] cannot contain '.'"
can you please help me out. thanks

location is a property of the objects you store in main_array, so try like this:
{
"mappings": {
"search_data": {
"properties": {
"main_array": {
"properties": {
"location": {
"type": "geo_point"
}
}
}
}
}
}
}
Note that as of ES 2.0 field names may not contain dots

Related

Finding State Short Name from JSON file with PHP

I have a JSON file that have all list of all the countries with their cities, and state. The file has this structure
"NO": {
"name": "Norway",
"states": {
"VA": {
"name": "Vest-Agder"
},
"RO": {
"name": "Rogaland"
},
"HO": {
"name": "Hordaland"
},
"SF": {
"name": "Sogn og Fjordane"
},
"MR": {
"name": "Møre og Romsdal"
},
"ST": {
"name": "Sør-Trøndelag"
},
"NO": {
"name": "Nord-Trøndelag"
},
"NT": {
"name": "Nordland"
},
"TR": {
"name": "Troms"
},
"FI": {
"name": "Finnmark"
},
"SJ": {
"name": "Svalbard"
},
"SJ": {
"name": "Jan Mayen"
},
"AK": {
"name": "Akershus"
},
"AA": {
"name": "Aust-Agder"
},
"BU": {
"name": "Buskerud"
},
"HE": {
"name": "Hedmark"
},
"OP": {
"name": "Oppland"
},
"OS": {
"name": "Oslo"
},
"TE": {
"name": "Telemark"
},
"VF": {
"name": "Vestfold"
},
"OF": {
"name": "Østfold"
}
}
},
What I am trying to achieve is to get the short name of state when user input the full name in the input field. For example if they add "Oslo" I will get "OS" in output
This is the code that I came up with but I am not getting the output.
$jsonitem = file_get_contents("countries-info.json");
$objitems = json_decode($jsonitem);
$findByname = function($name) use ($objitems) {
foreach ($objitems as $friend) {
if ($friend->name == $name) return $friend->state;
}
return false;
};
echo $findByname($_GET[code]) ?: 'No record found.';
Need advise.
Looking at the structure of your JSON you should loop $objitems->NO->states ( $objitems will contain the complete object, you only want the states)
So you need to change your foreach to:
foreach ($objitems->NO->states as $short => $state) {
if ($state->name == $name) return $short;
}
foreach ($objitems as $state => $friend) {
if ($friend->name == $name) return $state;
}

How to sort aggregations by top hits field (text field)? Or is there any possibility to sort aggregations by text field (without using _term)

As in title, I have a problem with sorting Elasticsearch aggregation by text field. Is there any possibility to do it? Using top hits or something like this? Now i'm using term aggregation and i can sort by aggregation field using _term, but i need to sort this aggregations by different field. I know how to do it with fields with numeric value. For instance using max, min, sum etc.
It will be great if i can do it like this (but i cant):
"aggs": {
"Variants": {
"terms": {
"field": "variant",
"order": {
"top_Song_hits": "asc"
}
},
"aggs": {
"top_Song_hits": {
"sum": {
"name": {
"order": "desc"
}
}
}
}
}
}
}
or like this:
{
"aggs": {
"Variants": {
"terms": {
"field": "variant",
"order": {
"name_agg": "asc"
}
},
"aggs": {
"name_agg": {
"terms": {
"field": "name"
}
}
}
}
}
}
Or
{
"aggs": {
"Variants": {
"terms": {
"field": "variant",
"order": {
"details": "asc"
}
},
"aggs": {
"details": {
"top_hits": {
"size": 1,
"_source": {
"include": ["name"]
}
}
}
}
}
}
}
In last case i get error:
"reason": "Invalid aggregation order path [details]. Buckets can only be sorted on a sub-aggregator path that is built out of zero or more single-bucket aggregations within the path and a final single-bucket or a metrics aggregation at the path end."
i found solution for my problem here:
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-collapse.html

Elastisearch Failed to JSON encode issue

I working on elastic search and I have 1K phone numbers when I pass this phone numbers array to elastic search to search users through phone numbers it gives me exception
Failed to JSON encode /var/app/current/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Serializers/SmartSerializer.php
Below is my Elasticsearch client initializing
$client = ClientBuilder::create()->setHosts([$host])->build();
And my working query in Elasticsearch
{
"_source": [
"id"
],
"query": {
"bool": {
"must": [
{
"term": {
"type": "user"
}
},
{
"bool": {
"should": [
{
"prefix": {
"phone": {
"value": "923047698099"
}
}
},
{
"prefix": {
"phone": {
"value": "92313730320"
}
}
},
.
.
.
]
}
}
],
"must_not": [
{
"has_child": {
"type": "blocked",
"query": {
"term": {
"user_id": "u-2"
}
}
}
},
{
"has_child": {
"type": "block",
"query": {
"term": {
"user_id": "u-2"
}
}
}
},
{
"term": {
"db_id": 2
}
}
]
}
}
}
I don't know that where I doing mistake. Either at client initializing or writing elasticserch query. I searched this issue but not usefull solution found or might be I did't understand clearly. But still I am stucked on this issue that how to solve this problem. Suggest any usefull link or solution.
Thanks

Elastic search geo point query filter

I am trying to use geo_point for distance but it always shows location type double not geo_point how can I set location mapped to geo_point .
Actually I have to find all records within 5km sorted.
"pin" : {
"properties" : {
"location" : {
"properties" : {
"lat" : {
"type" : "double"
},
"lon" : {
"type" : "double"
}
}
},
"type" : {
"type" : "string"
}
}
},
and when I am trying searches with this query below to find result within 5km of delhi lat long :
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"pin": {
"distance": "5",
"distance_unit": "km",
"coordinate": {
"lat": 28.5402707,
"lon": 77.2289643
}
}
}
}
}
}
It shows me error query_parsing_exception and No query registered for [pin]. I cannot figure out the problem. It always throws this exception
{
"error": {
"root_cause": [
{
"type": "query_parsing_exception",
"reason": "No query registered for [pin]",
"index": "find_index",
"line": 1,
"col": 58
}
],
"type": "search_phase_execution_exception",
"reason": "all shards failed",
"phase": "query",
"grouped": true,
"failed_shards": [
{
"shard": 0,
"index": "find_index",
"node": "DtpkEdLCSZCr8r2bTd8p5w",
"reason": {
"type": "query_parsing_exception",
"reason": "No query registered for [pin]",
"index": "find_index",
"line": 1,
"col": 58
}
}
]
},
"status": 400
}
Please help me to figure out this problem. how can I set geo_point and solve this exception error and status 400 and all_shards_failed error
You simply need to map your pin type like this, i.e. using the geo_point data type:
# 1. first delete your index
DELETE shouut_find_index
# 2. create a new one with the proper mapping
PUT shouut_find_index
{
"mappings": {
"search_shouut": {
"properties": {
"location": {
"type": "geo_point"
},
"type": {
"type": "string"
}
}
}
}
}
Then you can index a document like this
PUT shouut_find_index/search_shouut/1
{
"location": {
"lat": 28.5402707,
"lon": 77.2289643
},
"type": "dummy"
}
And finally your query can look like this
POST shouut_find_index/search_shouut/_search
{
"query": {
"filtered": {
"filter": {
"geo_distance": {
"distance": "5km",
"location": {
"lat": 28.5402707,
"lon": 77.2289643
}
}
}
}
}
}

How to display company name "only" on friends work history (facebook api)

I have been getting my facebook friends work history. But the result is an array whose content is as follows :
{
"id": "xxx",
"friends": {
"data": [
{
"name": "Indiarto Priadi",
"work": [
{
"employer": {
"id": "111178415566505",
"name": "Liputan 6 SCTV"
}
},
{
"employer": {
"id": "107900732566334",
"name": "SCTV"
}
}
],
"id": "502163984"
},
{
"name": "Agustin Kertawijaya",
"work": [
{
"employer": {
"id": "138215336225242",
"name": "Trader Corporation (Canada)"
},
"location": {
"id": "110941395597405",
"name": "Toronto, Ontario"
},
"position": {
"id": "168673399850791",
"name": "Desktop operator <Pre press>"
},
"start_date": "2006-06-01",
"end_date": "2008-06-01"
},
{
"employer": {
"id": "114464911939560",
"name": "Merrill Corporation Canada"
},
"location": {
"id": "110941395597405",
"name": "Toronto, Ontario"
},
"position": {
"id": "190075304347365",
"name": "Financial Print Project Manager"
},
"start_date": "2006-06-01",
"end_date": "2011-10-01"
}
],
"id": "511990261"
}
],
"paging": {
"next": "https://graph.facebook.com/1065251285/friends?limit=2&fields=name,work&offset=2&__after_id=511990261"
}
}
}
Now i want to display "only" the employer name on my page, but i can't find the way to do that.
Here is my code :
$userFriends = $facebook->api('/'.$userId.'/friends');
for($i=0;$i<=3;$i++){ //retrieved friends (max 4 persons)
$value=$userFriends["data"][$i];
echo "<div id='$value[id]'>";
$profile = $facebook->api("/".$value["id"]);
$friendsWork = $facebook->api("/".$value["id"]."?fields=work");
echo "<strong>".$profile["name"]."<br></strong>";
echo " <img src='https://graph.facebook.com/".$value["id"]."/picture'><br>";
echo "Username : ".$profile["username"]."<br>";
echo "Local : ".$profile["locale"]."<br>";
echo "Birthdate : ".$profile["birthday"]."<br>";
print_r($friendsWork); // <--- the result is an array
echo "<hr>";
echo "</div>";
}
Does anyone know how to display the company(employer) name only?
any answers would be greatly appreciated. Thank You
Here you go, nothing fancy, I just did what I said in my comment
$json = '{
"id": "xxx",
"friends": {
"data": [
{
"name": "Indiarto Priadi",
"work": [
{
"employer": {
"id": "111178415566505",
"name": "Liputan 6 SCTV"
}
},
{
"employer": {
"id": "107900732566334",
"name": "SCTV"
}
}
],
"id": "502163984"
},
{
"name": "Agustin Kertawijaya",
"work": [
{
"employer": {
"id": "138215336225242",
"name": "Trader Corporation (Canada)"
},
"location": {
"id": "110941395597405",
"name": "Toronto, Ontario"
},
"position": {
"id": "168673399850791",
"name": "Desktop operator <Pre press>"
},
"start_date": "2006-06-01",
"end_date": "2008-06-01"
},
{
"employer": {
"id": "114464911939560",
"name": "Merrill Corporation Canada"
},
"location": {
"id": "110941395597405",
"name": "Toronto, Ontario"
},
"position": {
"id": "190075304347365",
"name": "Financial Print Project Manager"
},
"start_date": "2006-06-01",
"end_date": "2011-10-01"
}
],
"id": "511990261"
}
],
"paging": {
"next": "https://graph.facebook.com/1065251285/friends?limit=2&fields=name,work&offset=2&__after_id=511990261"
}}}'; // remember the last two closing curlys, you left them out of the code block in the OP.
$obj = json_decode($json);
foreach ($obj->friends->data as $friend) {
echo '<h1>' . $friend->name . '</h1>';
foreach ($friend->work as $job) {
echo 'Employee: ' . $job->employer->name . '<br/>';
}
echo '<hr>';
}
Output:
Indiarto Priadi
Employee: Liputan 6 SCTV
Employee: SCTV
--------------------------------------
Agustin Kertawijaya
Employee: Trader Corporation (Canada)
Employee: Merrill Corporation Canada
--------------------------------------
You just have to parse the array you obtained, like this-
$userFriends = $facebook->api('/'.$userId.'/friends?fields=work,name');
foreach($userFriends['data'] as $friend)
{
$friend_name = $friend['name'];
$emp_name=array();
// list of all employers of this friend
if(isset($friend['work']))
{
foreach($friend['work'] as $work)
{
array_push($emp_name, $work['employer']['name']);
}
}
else
{
$emp_name = "N.A.";
}
}

Categories