I was not able to find a working example on how to query Elasticsearch using the completion suggester in PHP (elasticsearch-php).
Querying via CURL, e.g.
curl -X POST 'localhost:9200/tstidx/_suggest?pretty' -d '{
"try" : {
"text" : "a",
"completion" : {
"field" : "suggest"
}
}
}'
works, so the only problem is the query part in PHP.
How do I use the API to query Elasticsearch using the completion suggester?
The PHP ES client has a method called suggest that you can use for that purpose:
$params = [
'index' => 'tstidx',
'body' => [
'try' => [
'text' => 'a',
'completion' => [ 'field' => 'suggest' ]
]
]
];
$client = ClientBuilder::create()->build();
$response = $client->suggest($params);
Using the PHP elasticsearch API
<?Php
include 'autoload.php';
$elastic_search = new ElasticApiService();
$search_params = array(
'index' => 'my_index',
'search_type' => 'match',
'search_key' => 'citynamefield',
'search_value' => 'orlando'
);
$search_results = $elastic_search->searchElastic($search_params);
echo '<pre>';
print_r($search_results);
Related
unfortunately our project runs on PHP 7.0 and we cannot upgrade it for now. And Twilio's library uses PHP 7.2+ on the version that contains the trusthub API support.
So I'm trying to do the request "Create EndUser of type: customer_profile_business_information" from this doc page using Guzzle instead of their library, and I'm following instructions from the curl example.
Everything worked well except the Attributes field that looks like it's being ignored, it's returning a blank object and of course on their interface it's also not showing.
So in case the link breaks, the curl code example is the following:
ATTRIBUTES=$(cat << EOF
{
"business_identity": "direct_customer",
"business_industry": "EDUCATION",
"business_name": "acme business",
"business_regions_of_operation": "USA_AND_CANADA",
"business_registration_identifier": "DUNS",
"business_registration_number": "123456789",
"business_type": "Partnership",
"social_media_profile_urls": "",
"website_url": "test.com"
}
EOF
)
curl -X POST https://trusthub.twilio.com/v1/EndUsers \
--data-urlencode "Attributes=$ATTRIBUTES" \
--data-urlencode "FriendlyName=friendly name" \
--data-urlencode "Type=customer_profile_business_information" \
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN
And here's the PHP code that I made:
<?php
// $company is a model
$token = base64_encode(\Config::get('twilio.accountSid') . ':' . \Config::get('twilio.authToken'));
$client = new \GuzzleHttp\Client(['base_uri' => 'https://trusthub.twilio.com/v1/', 'headers' => ['Authorization' => "Basic {$token}", 'Content-Type' => 'application/x-www-form-urlencoded']]);
$client->post("EndUsers", [
'form_params' => [
'FriendlyName' => $company->business_name,
'Type' => 'customer_profile_business_information',
'Attributes' => [
'business_name' => $company->business_name,
'business_identity' => 'direct_customer',
'business_type' => $company->business_type,
'business_industry' => $company->industry->twilio_name,
'business_registration_identifier' => 'EIN',
'business_registration_number' => $company->tax_id_number,
'business_regions_of_operation' => $company->region,
'website_url' => $company->website,
'social_media_profile_urls' => '',
]
]
]);
Is there something I'm missing here that it's not saving the Attributes data?
PS: the other fields (FriendlyName and Type) are being successfully saved.
Thank you!
Twilio developer evangelist here.
The Attributes property of Twilio resources tends to be a JSON string, and I think that's the case for this one too. So, rather than passing an array of attributes, you need to json_encode the array first. This should work for you:
<?php
// $company is a model
$token = base64_encode(\Config::get('twilio.accountSid') . ':' . \Config::get('twilio.authToken'));
$client = new \GuzzleHttp\Client(['base_uri' => 'https://trusthub.twilio.com/v1/', 'headers' => ['Authorization' => "Basic {$token}", 'Content-Type' => 'application/x-www-form-urlencoded']]);
$client->post("EndUsers", [
'form_params' => [
'FriendlyName' => $company->business_name,
'Type' => 'customer_profile_business_information',
'Attributes' => json_encode([
'business_name' => $company->business_name,
'business_identity' => 'direct_customer',
'business_type' => $company->business_type,
'business_industry' => $company->industry->twilio_name,
'business_registration_identifier' => 'EIN',
'business_registration_number' => $company->tax_id_number,
'business_regions_of_operation' => $company->region,
'website_url' => $company->website,
'social_media_profile_urls' => '',
])
]
]);
I have a json file which I looped through it and index it in elastic. and after that I want to be able to search through my data.
this is my json file :
https://github.com/mhndev/iran-geography/blob/master/tehran_intersection.json
which looks like :
{
"RECORDS":[
{
"first":{
"name":"ابن بابویه",
"slug":"Ibn Babawayh"
},
"second":{
"name":"میرعابدینی",
"slug":"Myrabdyny"
},
"latitude":"35.601605",
"longitude":"51.444208",
"type":"intersection",
"id":1,
"search":"ابن بابویه میرعابدینی,Ibn Babawayh Myrabdyny,ابن بابویه تقاطع میرعابدینی,Ibn Babawayh taghato Myrabdyny",
"name":"ابن بابویه میرعابدینی",
"slug":"Ibn Babawayh Myrabdyny"
},
...
]
}
when my query is : "mir", I expect my result to be records which has "mirabedini", "mirdamad", "samir", and every other word which contains this string.
but I just get words which are exactly "mir"
and this is my php code for search :
$fields = ['search','slug'];
$params = [
'index' => 'digipeyk',
'type' => 'location',
'body' => [
'query' => [
'match' => [
'fields' => $fields,
'query' => $_GET['query']
]
],
'from' => 0,
'size' => 10
]
];
$client = ClientBuilder::create()->build();
$response = $client->search($params);
and also this my php code for indexing documents.
$client = ClientBuilder::create()->build();
$deleteParams = ['index' => 'digipeyk'];
$response = $client->indices()->delete($deleteParams);
$intersections = json_decode(file_get_contents('data/tehran_intersection.json'), true)['RECORDS'];
$i = 1;
foreach($intersections as $intersection){
echo $i."\n";
$params['index'] = 'digipeyk';
$params['id'] = $intersection['id'];
$params['type'] = 'location';
$params['body'] = $intersection;
$response = $client->index($params);
$i++;
}
I'm using php 7 and elasticsearch 2.3
match query doesn't support wildcard query by default, so you have to use wildcard instead of that.
$fields = ['search','slug'];
$params = [
'index' => 'digipeyk',
'type' => 'location',
'body' => [
'query' => [
'wildcard' => [
'query' => '*'.$_GET['query'].'*'
]
],
'from' => 0,
'size' => 10
]
];
$client = ClientBuilder::create()->build();
$response = $client->search($params);
For more information about wildcard in elastic visit following link : https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-wildcard-query.html
For that:
'query' => $_GET['query']
You will be burn in hell :D
I recently tried to use ES. So I set it up in a cloud 9 environnement. I inserted data using a curl request file and I can see them with
http://mydomain/ingredients/aliments/_search?size=350&pretty=true
I then tried to set up elastic SDK (v.2.0) with Silex but I can't get the same output...
Here is my code :
$client = $app['elasticsearch'];
$params = array(
'size' => 350,
'index' => 'ingredients',
'type'=>'aliment',
'body' => array(
'query'=>array(
'match_all' => new \stdClass()
)
)
);
$ingredients = $client->search($params);
The output is NULL but when I do the following :
$params = array(
'index' => 'ingredients',
'type' => 'aliment'
);
$count = $client->count($params);
The output is as expected : {"count":240,"_shards":{"total":5,"successful":5,"failed":0}}
I've already spent a few hours trying to figure what's going on, I tried to replace the 'query' args with a json string, I tried empty array instead of the new stdClass but nothing seems to work.
Edit : I read the documentation again and tried the official example :
$client = $app['elasticsearch'];
$params = [
"search_type" => "scan", // use search_type=scan
"scroll" => "30s", // how long between scroll requests. should be small!
"size" => 50, // how many results *per shard* you want back
"index" => "ingredients",
"body" => [
"query" => [
"match_all" => []
]
]
];
$output = $client->search($params);
$scroll_id = $output['_scroll_id']; /*<<<This works****/
while (\true) {
// Execute a Scroll request
$response = $client->scroll([
"scroll_id" => $scroll_id, //...using our previously obtained _scroll_id
"scroll" => "30s" // and the same timeout window
]
);
var_dump($response); /*<<<THIS IS NULL****/
...
}
And unfortunately got same null result...
What am I doing wrong ?
Thanks for reading.
In my case it works this way:
$json = '{
"query": {
"match_all": {}
}
}';
$params = [
'type' => 'my_type',
'body'=> $json
];
I found out that the inserted data was malformed.
Accessing some malformed data via browser URL seems to be OK but not with a curl command line or the SDK.
Instead of {name:"Yaourt",type:"",description:""} , I wrote {"name":"Yaourt","description":""} in my requests file and now everything work as expected !
#ivanesi 's answer works. You may also try this one:
$params["index"] = $indexName;
$params["body"]["query"]["match_all"] = new \stdClass();
I am trying to create a spatial database with neo4j 3.0.2 and neo4j-spatial for 3.0.2. I have installed the plugin and I have checked that the plugin is running with cURL curl -v http://neo4j:neo4j#localhost:7474/db/data/ which outputs following:
{
"extensions" : {
"SpatialPlugin" : {
"addSimplePointLayer" : "http://localhost:7474/db/data/ext/SpatialPlugin/graphdb/addSimplePointLayer",
"addNodesToLayer" : "http://localhost:7474/db/data/ext/SpatialPlugin/graphdb/addNodesToLayer",
"findClosestGeometries" : "http://localhost:7474/db/data/ext/SpatialPlugin/graphdb/findClosestGeometries",
"addGeometryWKTToLayer" : "http://localhost:7474/db/data/ext/SpatialPlugin/graphdb/addGeometryWKTToLayer",
"findGeometriesWithinDistance" : "http://localhost:7474/db/data/ext/SpatialPlugin/graphdb/findGeometriesWithinDistance",
"addEditableLayer" : "http://localhost:7474/db/data/ext/SpatialPlugin/graphdb/addEditableLayer",
"addCQLDynamicLayer" : "http://localhost:7474/db/data/ext/SpatialPlugin/graphdb/addCQLDynamicLayer",
"addNodeToLayer" : "http://localhost:7474/db/data/ext/SpatialPlugin/graphdb/addNodeToLayer",
"getLayer" : "http://localhost:7474/db/data/ext/SpatialPlugin/graphdb/getLayer",
"findGeometriesInBBox" : "http://localhost:7474/db/data/ext/SpatialPlugin/graphdb/findGeometriesInBBox",
"updateGeometryFromWKT" : "http://localhost:7474/db/data/ext/SpatialPlugin/graphdb/updateGeometryFromWKT",
"findGeometriesIntersectingBBox" : "http://localhost:7474/db/data/ext/SpatialPlugin/graphdb/findGeometriesIntersectingBBox"
}
},
"node" : "http://localhost:7474/db/data/node",
"relationship" : "http://localhost:7474/db/data/relationship",
"node_index" : "http://localhost:7474/db/data/index/node",
"relationship_index" : "http://localhost:7474/db/data/index/relationship",
"extensions_info" : "http://localhost:7474/db/data/ext",
"relationship_types" : "http://localhost:7474/db/data/relationship/types",
"batch" : "http://localhost:7474/db/data/batch",
"cypher" : "http://localhost:7474/db/data/cypher",
"indexes" : "http://localhost:7474/db/data/schema/index",
"constraints" : "http://localhost:7474/db/data/schema/constraint",
"transaction" : "http://localhost:7474/db/data/transaction",
"node_labels" : "http://localhost:7474/db/data/labels",
"neo4j_version" : "3.0.2"
* Connection #0 to host localhost left intact
}* Closing connection #0
Now I can create a new simplePointLayer:
// define entity manager
$client = $this->get('neo4j.spatial_manager')->getClient();
// 1. Create a pointlayer
$request = $client->request('POST',
'/db/data/ext/SpatialPlugin/graphdb/addSimplePointLayer',
[
'json' => [
'layer' => 'geom',
'lat' => 'lat',
'lon' => 'lon',
],
]
);
var_dump($request);
This creates the spatial root node with the rTree. But when I now want to create a spatial index with following:
// 2. Create a spatial index
$request = $client->request('POST',
'/db/data/index/node/',
[
'json' => [
'name' => 'geom',
'config' => [
'provider' => 'spatial',
'geometry_type' => 'point',
'lat' => 'lat',
'lon' => 'lon',
],
],
]
);
var_dump($request);
I am confronted with the error-message:
"message" : "No index provider 'spatial' found.
What am I doing wrong? I have checked a lot of forums and so on, but the answer always seems to be to install the spatial plugin, which I have and it seems to be working according to the first output.
EDIT 15.06.2016
Whats weird is that I can add nodes to the rTree:
// Create a node with spatial data
$json = [
'team' => 'REDBLUE',
'name' => 'TEST',
'lat' => 25.121075,
'lon' => 89.990630,
];
$response = $client->request('POST',
'/db/data/node',
[
'json' => $json
]
);
$node = json_decode($response->getBody(), true)['self'];
// Add the node to the layer
$response = $client->request('POST',
'/db/data/ext/SpatialPlugin/graphdb/addNodeToLayer',
[
'json' => [
'layer' => 'geom',
'node' => $node,
],
]
);
$data = json_decode($response->getBody(), true);
var_dump($data);
And I can query the nodes through REST:
$request = $client->request('POST',
'/db/data/ext/SpatialPlugin/graphdb/findGeometriesWithinDistance',
[
'json' => [
'layer' => 'geom',
'pointX' => 89.99506,
'pointY' => 25.121260,
'distanceInKm' => 10,
],
]
);
$data = json_decode($request->getBody(), true);
var_dump($data);
But why is it not letting me create an index? Or does it do the indexing automatically? And if so, how can I query using CYPHER (in the web console for example)?
Any help would be appreciated! Cheers
The index provider was removed (back then it was the only means to provide integration with Cypher), in favor of user defined procedures for Spatial.
see: https://github.com/neo4j-contrib/spatial/blob/master/src/test/java/org/neo4j/gis/spatial/procedures/SpatialProceduresTest.java#L113
As this is a new major release (for 3.0) we found it sensible to remove the index provider.
Guzzle client creates by default from this code
$client->get('https://example.com/{?a}', array('a' => array('c','d')));
this url
https://example.com/?a=c,d
What is the best practice to send array in query string in RESTful application? The question is, how can I determine on the server side whether c,d is a string or an array? Isn't it better to send arrays using square brackets, e.g. a[]=c&a[]=d? How can I set Guzzle to use square brackets? Or it is better to use JSON encoded variables? On the server side I'm using Tonic.
Working Solution:
$vars = array('state[]' => array('Assigned','New'), 'per_page' => $perPage, 'page' => $pageNumber);
$query = http_build_query($vars, null, '&');
$string = preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '=', $query); // state[]=Assigned&state[]=New
$client = new Client([follow instruction to initialize your client ....]);
$response = $client->request('GET', $uri, ['query' => $string]);
Now you have same name parameters in your request.
Dung.
Source: http_build_query with same name parameters
It seems the answer is here.
I wanted to do something like ?status[]=first&status[]=second
You can do this in Guzzle like shown in the link above:
$client = new Client('http://test.com/api');
$request = $client->get('/resource');
$query = $request->getQuery();
$query->set('status', array('first', 'second'));
Guzzle has a helper function you can use called build_query(). This uses PHP's http_build_query().
Here's an example of how to use it:
$params = [
'a[]' => [
'c',
'd'
],
'page' => 1
];
$query = \GuzzleHttp\Psr7\build_query($params);
$response = $client->request('GET', 'https://example.com/', [
'query' => $query
]);
I'm not 100% sure this quite answers the question. But I found the question while looking for how to construct complex queries using Guzzle and none of the answers here were the solution I ended up using. I'm adding it here in case it's ever useful for any other devs.
Using Guzzle 6, you can do this type of request:
$endPoint = "https://example.com";
$queryParams = [
'a' => [
[
"b" => "c"
]
]
];
$options = [
'debug' => true, // so you can see what the request looks like
'query' => $queryParams
];
$client->request('GET', $endPoint, $options);
As a real world example, query params like this:
$queryParams = [
'filters' => [
[
"field" => "status",
"value" => "open",
"operator" => "equal"
],
[
"field" => "total",
"operator" => "greater_than",
"value" => 50
],
],
'limit' => 500,
'start' => 7
];
produce a url like this:
https://example.com?filters=[{"field":"status","operator":"equal","value":"open"},{"field":"total","operator":"less_than","value":50}]&limit=500&start=7
The point being that the query key of the $options array, seems very powerful. I'd recommend having a play with that before going down the route of writing complex regular expressions.
$query = array('x' => array(
'a',
'b',
'c'
));
$query_string = http_build_query($query, null, '&'); //build query string
$query_string = preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '[]=', $query_string); //x[]=a&x[]=b
$response = $guzzle->client->get($path, array('query' => $query_string)); //Make guzzle request
return json_decode($response->getBody()->getContents()); //Return JSON decoded array
This is how you can process x with array of values in guzzle, tested with version 6 or later