php full text search in elasticsearch - php

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

Related

How to Post with request to create new data from form using guzzle - Laravel

I have this function in my controller:
public function store(Request $request)
{
$client = new Client();
$headers = [
'Authorization' => $token,
'Content-Type' => 'application/json'
];
$body = '{
"DocNo": 1167722,
"AOQty": 0,
"TL": [
{
"Key": 11678,
"Code": "Screw Hex",
"Detail": true,
"DTL": []
}
]
}';
$request = new Psr7Request('POST', 'http://example.com/api/Order/', $headers, $body);
$res = $client->sendAsync($request)->wait();
echo $res->getBody();
}
that will store the data to the external API
but i want to POST the data from a form
when i work with normal routing (not API) i usually do this:
'Key' => $request->Key,
how can i achieve the above with guzzle?
currently when i submit the form from the view it will submit the above function (store) as static data, how can i submit the data from the form?
UPDATE:
When i use Http as showing below:
$store = Http::withHeaders([
'Content-Type' => 'application/json',
'Authorization' => $token,
])->post('http://example.com/api/Order/', [
'DocNo' => "SO-000284",
'AOQty' => 0.0,
'TL[Key]' => 11678,
'TL[Code]' => "SCREW HEX CAPHEAD 6X30MM",
'TL[Detail]' => true,
'TL[DTL]' => [],
]);
echo $store;
it will store everything before [TL] Array, it won't store anything of:
'TL[Key]' => 11678,
'TL[Code]' => "SCREW HEX CAPHEAD 6X30MM",
'TL[Detail]' => true,
'TL[DTL]' => [],
am i doing it wrong?
You can use HTTP client provided by Laravel.
$response = Http::withToken($token)->post('http://example.com/users', $request->only(['request_param_1', 'request_param_2']));
Or
$data = [];
$data['param_1'] = $request->get('param_1');
$data['param_2'] = $request->get('param_2');
$data['param_3'] = $request->get('param_3');
$response = Http::withToken($token)->post('http://example.com/users', $data);
Edit
$data = [
'DocNo' => "SO-000284",
'AOQty' => 0.0,
'TL' => [
'key' => 11678,
'Code' => "SCREW HEX CAPHEAD 6X30MM",
'Detail' => true,
'DTL' => [],
]
];
SOLUTION:
Using Http client:
'TL' => array ([
'Dtl' => "",
'Code' => "Screw Hex",
'IsDetail' => true,
"DTL" => [],
])
]);

use query_string and range in elasticsearch php client [query_string] malformed query, expected [END_OBJECT] but found [FIELD_NAME]

i use below code and get below error
for connect php to elasticsearch i use elasticsearch php client
$params = [
'index'=>'index1,index2',
'from'=>$startfrom,
'size'=>$maxperpage,
'sort' => array('id:desc'),
'body' => [
'query' => [
'query_string' => [
'query' => "\"$search_text\""
]
]
],
];
if($limit_time['start']){
$params['body']['query']['range']['date_insert']['gte']=$limit_time['start'];
}
if($limit_time['end']){
$params['body']['query']['range']['date_insert']['lte']=$limit_time['end'];
}
error :
{"error":{"root_cause":[{"type":"parsing_exception","reason":"[query_string] malformed query, expected [END_OBJECT] but found [FIELD_NAME]","line":1,"col":104}],"type":"parsing_exception","reason":"[query_string] malformed query, expected [END_OBJECT] but found [FIELD_NAME]","line":1,"col":104},"status":400}
You should try something like this instead. The query_string and the range queries need to be combined into a bool/filter query:
$params = [
'index'=>'index1,index2',
'from'=>$startfrom,
'size'=>$maxperpage,
'sort' => array('id:desc'),
'body' => [
'query' => [
'bool' => [
'filter' => [
[
'query_string' => [
'query' => "\"$search_text\""
]
]
]
]
]
],
];
$range = ['range' => ['date_insert' => []]]
if($limit_time['start']){
$range['range']['date_insert']['gte'] = $limit_time['start'];
}
if($limit_time['end']){
$range['range']['date_insert']['lte'] = $limit_time['end'];
}
$params['body']['query']['bool']['filter'][] = $range;
i solved problem
but thanks a lot "Val" for your help
i use below code :
$params = [
'index'=>'index1,index2',
'from'=>$startfrom,
'size'=>$maxperpage,
'sort' => array('id:desc')
];
if($search_text){
$params['body']['query']['bool']['must'][0]['match_phrase']['src']=$search_text;
}
if($use_time_status){
if($limit_time['start']){
$params['body']['query']['bool']['must'][1]['range']['date_insert']['gte']=$limit_time['start'];
}
if($limit_time['end']){
$params['body']['query']['bool']['must'][1]['range']['date_insert']['lte']=$limit_time['end'];
}
}

GET data from Couchdb using Guzzle in php

I'm getting data from Couchdb to PHP using Guzzle library. Now I fetch data in POST format like this:
But I need response like this:
{
"status": 200,
"message": "Success",
"device_info": {
"_id": "00ab897bcb0c26a706afc959d35f6262",
"_rev": "2-4bc737bdd29bb2ee386b967fc7f5aec9",
"parent_id": "PV-409",
"child_device_id": "2525252525",
"app_name": "Power Clean - Antivirus & Phone Cleaner App",
"package_name": "com.lionmobi.powerclean",
"app_icon": "https://lh3.googleusercontent.com/uaC_9MLfMwUy6pOyqntqywd4HyniSSxmTfsiJkF2jQs9ihMyNLvsCuiOqrNxNYFq5ko=s3840",
"last_app_used_time": "12:40:04",
"last_app_used_date": "2019-03-12"
"bookmark": "g1AAAABweJzLYWBgYMpgSmHgKy5JLCrJTq2MT8lPzkzJBYorGBgkJllYmiclJxkkG5klmhuYJaYlW5paphibppkZmRmB9HHA9BGlIwsAq0kecQ",
"warning": "no matching index found, create an index to optimize query time"
} }
I only remove "docs": [{}] -> Anyone know I remove this ?
check My code:
$response = $client->post(
"/child_activity_stat/_find",
[GuzzleHttp\RequestOptions::JSON => ['selector' => ['parent_id' => ['$eq' => $userid], 'child_device_id' => ['$eq' => $deviceid]],]]
);
if ($response->getStatusCode() == 200) {
$result = json_decode($response->getBody());
$r = $response->getBody();
json_output(200, array(
'status' => 200,
'message' => 'Success',
"device_info" => $result
));
}
You just need to modify your data structure.
NOTE: Maybe you should add a limit of 1 if you want to only get one document. You will also need to validate that the result['docs'] is not empty.
Example:
<?php
$response = $client->post(
"/child_activity_stat/_find",
[GuzzleHttp\ RequestOptions::JSON => ['selector' => ['parent_id' => ['$eq' => $userid], 'child_device_id' => ['$eq' => $deviceid]], ]]
);
if ($response->getStatusCode() == 200) {
// Parse as array
$result = json_decode($response->getBody(),true);
// Get the first document.
$firstDoc = $result['docs'][0];
// Remove docs from the response
unset($result['docs']);
//Merge sanitized $result with $deviceInfo
$deviceInfo = array_merge_recursive($firstDoc,$result);
json_output(200, array(
'status' => 200,
'message' => 'Success',
"device_info" => $deviceInfo
));
}
In couchdb use PUT request is used to edit or to add data and DELETE remove data
$client = new GuzzleHttp\Client();
// Put request for edit
$client->put('http://your_url', [
'body' => [
'parent_id' => ['$eq' => $userid],
'child_device_id' => ['$eq' => $deviceid]
],
'allow_redirects' => false,
'timeout' => 5
]);
// To delete
$client->delete('htt://my-url', [
'body' = [
data
]
]);

ElasticSearch PHP API Search by Field

Resolved
I am trying to get a results back using the official elasticsearch 5.0 php package. I can get the desired results via URL and cURL.
http://localhost:9200/index/doctype/_search?q=status:available
I get 8 hits and 8 hit results, as expected.
curl -XGET 'localhost:9200/index/doctype/_search?pretty' -d'
{
"query" : {
"term" : { "status" : "available" }
}
}'
I get 8 hits and 8 hit results, as expected.
Using the following various bits of code, I get 8 results but 0 hits.
$params['body']['query']['term']['status'] = 'available';
$params['q'] = 'status:available';
$params['body'] = [
'query' => [
'bool' => [
'must' => [
['match' => ['status' => 'available']],
]
]
]
];
Called via:
$params = [
'index' => 'index',
'type' => 'doctype',
];
$skip = !empty($_GET['page']) ? (int)$_GET['page'] - 1 : 0;
$listings_per_page = 25;
$params['from'] = $skip * $per_page;
$params['size'] = $per_page;
// show only available
$params['body'] = [
'query' => [
'bool' => [
'must' => [
['match' => ['status' => 'available']],
]
]
]
];
$hosts = [env('ES_HOST', 'elasticsearch') . ':' . env('ES_PORT', '9200')];
$client = ClientBuilder::create()->setHosts($hosts)->build();
$es_results = $client->search($params);
I have the index and doctype set properly in the $params as well in other bits of code. What could I be doing wrong here?
It is very likely that your from and size parameters are not computed correctly and from might be higher than 8, hence why you see results.hits.total: 8 but nothing in results.hits.hits
Make sure that from is 0 and size is at least 8 (default is 10) and you'll see your hits.

Elasticsearch completion suggester query in PHP

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);

Categories