Update by query (updateByQuery) Elasticsearch-PHP - php

I am Using Elasticsearch 2.3 along with the official php driver. The updateByQuery is giving me troubles to use in php. A little help on how to use it will be appreciated.
$client = \Elasticsearch\ClientBuilder::create()->setHosts(['127.0.0.1:9200'])->build();
# Request
$updateRequest = [
'index' => 'gorocket',
'type' => 'logs',
'body' => [
'query' => [
'filtered' => [
'filter' => [
'bool' => [
'must' =>
[
[
'match' => [ 'enabled' => 1 ],
],
]
]
]
]
]
]
]
];
# Update
$results = $client->updateByQuery($updateRequest);
Basically i want to update a couple of document fields(name,price) that matches a certain query
Thank you.

So, with the help of how the CURL api works i managed to come up with a way.
First you need to edit your elasticsearch.yml to allow Scripting. Append the following lines at the end.
script.engine.groovy.inline.search: on
script.engine.groovy.inline.aggs: on
script.engine.groovy.inline.update: on
There after you can start doing batch updates using queries as the example bellow.
$client = \Elasticsearch\ClientBuilder::create()->setHosts(['127.0.0.1:9200'])->build();
# Request
$updateRequest = [
'index' => 'testindex',
'type' => 'logs',
'conflicts' => 'proceed',
'body' => [
'query' => [
'filtered' => [
'filter' => [
'bool' => [
'must' =>
[
[
'match' => [ 'enabled' => 1 ],
],
]
]
]
]
],
'script' => [
'inline' => 'ctx._source.enabled = value',
'params' => [
'value' => 0
]
]
]
]
];
# Update
$results = $client->updateByQuery($updateRequest);
That's it. It is not easily and well documented as of now so.

I want to add a small addition to the previous answer
You may not add the following params in elasticsearch.yml
script.engine.groovy.inline.search: on
script.engine.groovy.inline.aggs: on
script.engine.groovy.inline.update: on
And your query will be:
$client = \Elasticsearch\ClientBuilder::create()->setHosts(['127.0.0.1:9200'])->build();
# Request
$updateRequest = [
'index' => 'testindex',
'type' => 'logs',
'conflicts' => 'proceed',
'body' => [
'query' => [
'filtered' => [
'filter' => [
'bool' => [
'must' => [
[
'match' => [ 'enabled' => 1 ],
],
]
]
]
]
],
'script' => [
'lang' => 'painless',
'source' => 'ctx._source.enabled = params.value',
'params' => [
'value' => 0
]
]
]
];
# Update
$results = $client->updateByQuery($updateRequest);

Related

If else statement in elasticsearch query construction

I'm using elasticsearch php and trying to optimize my query contraction in one place. Typical Elasticsearch query like:
$params = [
'index' => 'my_index',
'type' => 'my_type',
'body' => [
'query' => [
'bool' => [
'must' => [
[ 'match' => [ 'testField' => 'abc' ] ],
[ 'match' => [ 'testField2' => 'xyz' ] ],
]
]
]
]
];
So the question is, does it possible to put conditional query in $params before 'match' string maybe like:
<?php if (isset($_GET['query'])) [ 'match' => [ 'testField' => 'abc' ] ]; ?>
Thank you in any advice
You can use this:
<?php
$must = [[ 'match' => [ 'testField2' => 'xyz' ] ] ];
if (isset($_GET['query']))
$must[] = [ 'match' => [ 'testField' => 'abc' ] ];
$params = [
'index' => 'my_index',
'type' => 'my_type',
'body' => [
'query' => [
'bool' => [
'must' => $must
]
]
]
];
or this;
<?php
$params = [
'index' => 'my_index',
'type' => 'my_type',
'body' => [
'query' => [
'bool' => [
'must' => [
[ 'match' => [ 'testField2' => 'xyz' ] ],
],
]
]
]
];
if (isset($_GET['query']))
$params['body']['query']['bool']['must'][] = [ 'match' => [ 'testField' => 'abc' ] ];

Elasticsearch search results filtering

I am new to Elasticsearch and I am using REST API for PHP to play around with data returned. I am using following code to retrieve data.
$params = [
'index' => 'my_search',
'type' => 'mytype',
'from' => 0,
'size' => 10,
'body' => [
'query' => [
'bool' => [
'must' => [
[ 'match' => [ 'validated' => true ] ],
[ 'match' => [ 'image' => true ] ]
]
]
],
'sort' => [
'created_at' => [ 'order' => 'asc']
]
]
];
Above code returns data perfectly matching "validated=>true" and "image=>true".
Further I want to add open text search like we use /_search/?q=Apple macbook. I have tried to use match, multi_match, query_string options, but couldn't get success.
So, I want to retrieve results from ES that have "validated=>true", "image=>true" and matches with text "Apple macbook".
Thanks in advance.
You can try with query_string or simple_query_string
$params = [
'index' => 'my_search',
'type' => 'mytype',
'from' => 0,
'size' => 10,
'body' => [
'query' => [
'bool' => [
'must' => [
[ 'match' => [ 'validated' => true ] ],
[ 'match' => [ 'image' => true ] ],
[ 'query_string' => [ 'query' => 'Apple macbook' ] ]
]
]
],
'sort' => [
'created_at' => [ 'order' => 'asc']
]
]
];
$params = [
'index' => 'my_search',
'type' => 'mytype',
'from' => 0,
'size' => 10,
'body' => [
'query' => [
'bool' => [
'must' => [
[ 'match' => [ 'validated' => true ] ],
[ 'match' => [ 'image' => true ] ],
[ 'simple_query_string' => [ 'query' => 'Apple macbook' ] ]
]
]
],
'sort' => [
'created_at' => [ 'order' => 'asc']
]
]
];
you can also do this by
enabling all_field mapping for your index, you can do that by following the below URL
https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-all-field.html
and then use the below ES query:
$params = [
'index' => 'my_search',
'type' => 'mytype',
'from' => 0,
'size' => 10,
'body' => [
'query' => [
'bool' => [
'must' => [
[ 'match' => [ '_all' => 'Apple macbook' ] ],
[ 'match' => [ 'validated' => true ] ],
[ 'match' => [ 'image' => true ] ]
]
]
],
'sort' => [
'created_at' => [ 'order' => 'asc']
]
]
];

ElasticSearch Delete by query not working in PHP

I am using Elastic search 5.x and the following code is working fine:
curl -XPOST "http://localhost:9200/test_index/test_info/_delete_by_query" -d'
{
"query": {
"match": {
"category_id": "21"
}
}
}'
But when I am trying the same in my php code, its not working:
$client->deleteByQuery([
'index' => 'test_index',
'type' => 'test_info',
'query' => [
'match' => [
['category_id' => 21]
]
]
]);
You need to provide your query array inside body array of your parameters:
$client->deleteByQuery([
'index' => 'test_index',
'type' => 'test_info',
'body' => [
'query' => [
'match' => [
['category_id' => 21]
]
]
]
]);
this an old question, previous comments don't work anymore in 2020 :
$client->deleteByQuery([
'index' => 'test_index',
(there were a type here) 'type' => 'test_info',
'body' => [
'query' => [
'match' => [
(there were an array here) ['category_id' => 21]
]
]
]
]);
So the final code is :
$client->deleteByQuery([
'index' => 'test_index',
'body' => [
'query' => [
'match' => [
'category_id' => 21
]
]
]

How to optimize elastic search query

I have been reading through elastic search docs over the last few months and have continued to optimize my query, but I can't seem to get a search query below 500-600ms. Locally with less data I can get responses in ~80-200ms.
To outline what I am trying to accomplish:
I have 12 different models in Laravel that are searchable from a single search bar. As someone types it is searched and returned in a list of results.
Currently, I have this for my search query. Are there any references for how I can improve this? I looked into multi_match, but I was having issues with partial matches and specifying all fields.
$results = $this->elastic->search([
'index' => config('scout.elasticsearch.index'),
'type' => $type ?? implode(',', array_keys($this->permissions, true, true)),
'body' => [
'query' => [
'bool' => [
'must' => [
[
'query_string' => [
'query' => "$searchQuery*",
],
],
],
'filter' => [
[
'term' => [
'account_id' => $accountId,
],
],
],
'should' => [
[
'term' => [
'_type' => [
'value' => 'customers',
'boost' => 1.3,
],
],
],
[
'term' => [
'_type' => [
'value' => 'contacts',
'boost' => 1.3,
],
],
],
[
'term' => [
'_type' => [
'value' => 'users',
'boost' => 1.3,
],
],
],
[
'term' => [
'_type' => [
'value' => 'chart_accounts',
'boost' => 1.2,
],
],
],
],
],
],
'from' => $from,
'size' => $size,
],
]);

Querying Elasticsearch with PHP

I'm having a little trouble translating some of the queries I use for elasticsearch into PHP readable queries.
For example this simple query works:
$query = $elastic->search([
body' => [
'query' => [
'match' => [
'myfield' => 'mymatchingresult'
]
]
]
]);
But what I'm trying to get to work follow below. There isn't an error, it just doesn't run. I must not be understanding the structure. The same query if placed in something like google extension sense seems to work. (With the php '=>' converted to ':' etc.)
$query = $elastic->search([
'body' => [
'query' => [
'filtered' => [
'query' => [
'query_string' => [
'query' => '*',
'analyze_wildcard' => 'true'
]
],
'filter' => [
'bool' => [
'must' => [
'query' => [
'query_string' => [
'analyze_wildcard' => 'true',
'query' => 'cn:name'
]
],
'range' => [
'#timestamp' => [
'from' => '2012-05-01',
'to' => '2016-05-01'
]
]
]
]
]
]
]
]
]);
Thank you for the help!
-John
As far as I can tell, the constraints in your bool/must filter must be enclosed in square brackets, i.e. bool/must should be a pure array, not an associative array.
Like this:
$query = $elastic->search([
'body' => [
'query' => [
'filtered' => [
'query' => [
'query_string' => [
'query' => '*',
'analyze_wildcard' => 'true'
]
],
'filter' => [
'bool' => [
'must' => [
[
'query' => [
'query_string' => [
'analyze_wildcard' => 'true',
'query' => 'cn:name'
]
]
],
[
'range' => [
'#timestamp' => [
'from' => '2012-05-01',
'to' => '2016-05-01'
]
]
]
]
]
]
]
]
]
]);

Categories