Elasticsearch and PHP. Combine match and multi_match in one query - php

I have three fields - one of integer type (field1) and two of decimal type (field2, field3). I want to be able to query by all fields. These separate queries work nice in my situation:
$params = [
'index' => 'test_index',
'type' => 'text_index_type',
'body' => [
'query' => [
'match' => [
'field1' => '12'
]
]
]
];
and this query works well:
$params = [
'index' => 'test_index',
'type' => 'text_index_type',
'body' => [
'query' => [
'multi_match' => [
'query' => '345',
'fields' => ['field2', 'field3']
]
]
]
];
If, however, I combine them:
$params = [
'index' => 'test_index',
'type' => 'text_index_type',
'body' => [
'query' => [
'match' => [
'field1' => '12'
],
'multi_match' => [
'query' => '345',
'fields' => ['field2', 'field3']
]
]
]
];
I get an error:
Uncaught exception 'Elasticsearch\Common\Exceptions\BadRequest400Exception' ... [match] malformed query, unexpected [FIELD_NAME] found [multi_match]
So, what is wrong with that and how can I fix it?
PS. In terms of SQL, this is what I want to achive:
SELECT * FROM mytable where field1 = 12 or field2 = 345 or field3 = 345

You can combine them with bool queries
$params = [
'index' => 'test_index',
'type' => 'test_index_type',
'body' => [
'query' => [
'bool' => [
'should' => [
[ 'match' => [ 'field1' => '12' ] ],
[ 'multi_match' => [ 'query' => '345',
'fields' => ['field2', 'field3']] ],
]
]
]
]
];
should equates to "OR" while must equates to "AND"

Related

How to create an elasticsearch bool query with php client?

The query returns this error.
Elasticsearch\Common\Exceptions\BadRequest400Exception: {"error":{"root_cause":[{"type":"parsing_exception","reason":"unknown query [query]","line":1,"col":62}],"type":"x_content_parse_exception","reason":"[1:62] [bool] failed to parse field [should]","caused_by":{"type":"parsing_exception","reason":"unknown query [query]","line":1,"col":62,"caused_by":{"type":"named_object_not_found_exception","reason":"[1:62] unknown field [query]"}}},"status":400} in
How can i write this query ? . In array first one is (manufacturer_code,ean) parent, other objects are nested.
$query = [
'bool' => [
'should' => [
['query' => [ //parent root
'query_string' => [
'fields' => ['manufacturer_code', 'ean'],
'query' => $search,
],
],
],
['nested' => [ //nested parent.lang
'path' => 'lang',
'query' => [
'query_string' => [
'fields' => 'lang.name',
'query' => $search ,
],
],
]],
['nested' => [ //nested parent.product_base.lang
'path' => 'product_base.lang',
'query' => [
'query_string' => [
'fields' => 'product_base.lang.meta_keywords',
'query' => $search ,
],
],
]],
],
'minimum_should_match' => 1,
],
];
You're almost there, in the first should clause you need to remove the first query, i.e. query_string should be at top level
$query = [
'bool' => [
'should' => [
['query_string' => [ //parent root <-- modify this clause
'fields' => ['manufacturer_code', 'ean'],
'query' => $search,
],
],
['nested' => [ //nested parent.lang
'path' => 'lang',
'query' => [
'query_string' => [
'fields' => 'lang.name',
'query' => $search ,
],
],
]],
['nested' => [ //nested parent.product_base.lang
'path' => 'product_base.lang',
'query' => [
'query_string' => [
'fields' => 'product_base.lang.meta_keywords',
'query' => $search ,
],
],
]],
],
'minimum_should_match' => 1,
],
];

PHP elasticsearch partial match

i want to search with elasticsearch and show out the result with php. i want to make partial match like it's in mysql for ex:
select * from table_name where title like '%abc%'
But my codes doesn`t work:
$params = [
'index' => 'my_index',
'type' => 'my_type',
'body' => [
'query' => [
'match' => [
'title' => '.*abc.*'
]
]
]
];
I was using 'match' instead of 'regex'
$params = [
'index' => 'my_index',
'type' => 'my_type',
'body' => [
'query' => [
'regexp' => [
'title' => '.*abc.*'
]
]
]
];

elasticsearch php client search query returns all documents

I've been trying to search using 'match' and 'fuzzy', but I keep getting all of the documents, whether they match or not.
I've tried these 3 incarnations of my search:
1.
$params = [
'index' => 'my_engine',
'type' => 'my_type',
'body' => [
'query' => [
'fuzzy' => [
'_all' => $keyword
]
]
]
];
$params = [
'index' => 'my_engine',
'type' => 'my_type',
'body' => [
'query' => [
'match' => [
'title' => 'members'
]
]
]
];
$params['index'] = 'my_engine';
$params['type'] = 'my_type';
$params['body']['query']['match']['title'] = 'members';
Did I miss something during indexing?
I didn't provide any mapping.

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

elasticsearch: search for parts of words

I'm trying to learn how to use elasticsearch (using elasticsearch-php for queries). I have inserted a few data, which look something like this:
['id' => 1, 'name' => 'butter', 'category' => 'food'],
['id' => 2,'name' => 'buttercup', 'category' => 'food'],
['id' => 3,'name' => 'something else', 'category' => 'butter']
Now I created a search query which looks like this:
$query = [
'filtered' => [
'query' => [
'bool' => [
'should' => [
['match' => [
'name' => [
'query' => $val,
'boost' => 7
]
]],
['match' => [
'category' => [
'query' => $val,
'boost' => 5
]
]],
],
]
]
]
];
where $val is the search term. This works nicely, the only problem I have: when I search for "butter", I find ids 1 and 3, but not 2, because the searchterm seems to match exact words only. Is there a way to search "within words", or, in mysql terms, to do something like WHERE name LIKE '%val%' ?
You can try the wildcard query
$query = [
'filtered' => [
'query' => [
'bool' => [
'should' => [
['wildcard' => [
'name' => [
'query' => '*'.$val.'*',
'boost' => 7
]
]],
['wildcard' => [
'category' => [
'query' => '*'.$val.'*',
'boost' => 5
]
]],
],
]
]
]
];
or the query_string query.
$query = [
'filtered' => [
'query' => [
'bool' => [
'should' => [
['query_string' => [
'default_field' => 'name',
'query' => '*'.$val.'*',
'boost' => 7
]],
['query_string' => [
'default_field' => 'category',
'query' => '*'.$val.'*',
'boost' => 7
]],
],
]
]
]
];
Both will work but are not really performant if you have lots of data.
The correct way of doing this is to use a custom analyzer with a standard tokenizer and an ngram token filter in order to slice and dice each of your tokens into small ones.

Categories