Allowing case-insensitive search with snowball_analyzer in Elasticsearch - php

First of all I'm completly new to ES. I created ES search criteria below for searching items which works fine but what I now need is, I want to turn make field into case-insensitive so that the search result would be the same for hello, HeLlo, HELLO so on.
I've read post below couldn't quiet apply to my example below because of my very limited knowledge:
Case insensitivity does not work
Elasticsearch Map case insensitive to not_analyzed documents
Elasticsearch Snowball Analyzer wants exact word
Removing not_analyzed from make doesn't help.
'indexes' => [
'my_project' => [
'client' => 'default',
'index_name' => 'hello',
'settings' => [
'index' => [
'analysis' => [
'analyzer' => [
'snowball_analyzer' => [
'type' => 'snowball',
'language' => 'English',
],
],
],
],
],
'types' => [
'item' => [
'mappings' => [
'uuid' => ['type' => 'string', 'index' => 'not_analyzed'],
'name' => ['type' => 'string', 'boost' => 8, 'analyzer' => 'snowball_analyzer'],
'make' => ['type' => 'string', 'index' => 'not_analyzed'],
]
],
],
],
],
These is the query that I created:
1
{
"query": {
"filtered": {
"query": {
"bool": {
"must": [
{
"term": {
"make": "HeLlo"
}
}
]
}
}
}
}
}

You have to add the "lowercase" filter. Here is an extract for a similar configuration I use:
settings:
index:
analysis:
analyzer:
custom_search_analyzer:
type: custom
tokenizer: standard
filter: [stopwords, asciifolding ,lowercase, snowball, elision, worddelimiter]
In your case, I guess you should change like this:
...
'settings' => [
'index' => [
'analysis' => [
'analyzer' => [
'snowball_analyzer' => [
'type' => 'snowball',
'language' => 'English',
'filter' => [ 'lowercase' ]
],
],
],
],
],
...

I went thru the answer in the first link I posted with my eyes open this time and it solved my problem too so my case-insensitive working example is:
{
"query": {
"filtered": {
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "HeLlo*"
}
}
]
}
}
}
}
}

Related

How to use MDword to generate multi-level nested Office Word?

effect picture:
https://i.stack.imgur.com/f2r3O.png
github address:
https://github.com/mkdreams/MDword
data:
$arr = [
[
"title1" => "title1",
"meeting_content"=>[
[
"title11" => "title11,title11",
"content11" => "content,content,content,content,content,content,content,content,content,"
],
[
"title22" => "title22,title22",
"content22" => "content,content,content,content,content,content,content,content,content,"
],
],
"children" => []
],
[
"title" => "title",
"meeting_content"=>[
],
"children"=>[
[
"title1" => "title1",
"meeting_content"=>[
[
"title11" => "title11,title11",
"content11" => "content,content,content,content,content,content,content,content,content,"
],
[
"title22" => "title22,title22",
"content22" => "content,content,content,content,content,content,content,content,content,"
],
],
],
[
"title2" => "title2",
"meeting_content"=>[
[
"title11" => "title11,title11",
"content11" => "content,content,content,content,content,content,content,content,content,"
],
[
"title22" => "title22,title22",
"content22" => "content,content,content,content,content,content,content,content,content,"
],
],
],
],
],
];
How to use MDword to generate multi-level nested Office Word?
Now I need to, using a MDword extension of PHP, write this multidimensional data into a Word document, I don't know what to do, it has the effect picture, and Github address, thank you
You can use pstyle.You can see the demo.
Details as follows(You must update to the latest version):
data
$numDatas = [
[
'title'=>'title-1',
'content'=>'content-1'
],
[
'title'=>'title-2',
'sub'=>[
[
'title'=>'subTitle-2-1',
'content'=>'content-2-1',
],
[
'title'=>'subTitle-2-2',
'content'=>'content-2-2',
],
]
],
[
'title'=>'title-3',
'sub'=>[
[
'title'=>'subTitle-3-1',
'content'=>'content-3-1',
],
[
'title'=>'subTitle-3-2',
'content'=>'content-3-2',
],
]
],
];
temple IMG:
https://i.stack.imgur.com/dS1U1.png
code
$TemplateProcessor->cloneP('num',count($numDatas));
foreach($numDatas as $idx => $numData) {
$TemplateProcessor->cloneP('num'.'#'.$idx,3);
$TemplateProcessor->setValue('num'.'#'.$idx.'#0',[['text' => $numData['title'], 'pstyle' => 'numstyle-level-1', 'type' => MDWORD_TEXT]]);
if(isset($numData['content'])) {
$TemplateProcessor->setValue('num'.'#'.$idx.'#1',[['text' => $numData['content'], 'pstyle' => 'numstyle-level-3', 'type' => MDWORD_TEXT]]);
}else{
$TemplateProcessor->deleteP('num'.'#'.$idx.'#1');
}
$subName = 'num'.'#'.$idx.'#2';
if(isset($numData['sub'])) {
$TemplateProcessor->cloneP($subName,count($numData['sub']));
foreach($numData['sub'] as $subIdx => $subData) {
$TemplateProcessor->cloneP($subName.'#'.$subIdx,2);
$TemplateProcessor->setValue($subName.'#'.$subIdx.'#0',[['text' => $subData['title'], 'pstyle' => 'numstyle-level-2', 'type' => MDWORD_TEXT]]);
$TemplateProcessor->setValue($subName.'#'.$subIdx.'#1',[['text' => $subData['content'], 'pstyle' => 'numstyle-level-3', 'type' => MDWORD_TEXT]]);
}
}else{
$TemplateProcessor->deleteP($subName);
}
}
$TemplateProcessor->deleteP('numstyle');
result IMG:
https://i.stack.imgur.com/sb0MB.png

Filter on multi match ES PHP

Starting to work on ES. I would like to be able to make a multi_match with a filter in PHP. I followed the official ES documentation but I don't understand my mistake.
Here is the code:
public function search_data_into_index($array)
{
$params = [
'index' => 'skills',
'type' => 'people',
'body' => [
'query' => [
'multi_match' => [
'query' => 'react',
'fields' => [$array[2]],
'fuzziness' => 'AUTO',
],
'filter' => [
'geo_distance' => [
'distance' => '300m',
'location' => '-25, -49'
]
]
]
]
];
$response = $this->client->search($params);
print_r($response);
}
Here my error :
{"error":{"root_cause":[{"type":"parsing_exception","reason":"[multi_match] malformed query, expected [END_OBJECT] but found [FIELD_NAME]","line":1,"col":94}],"type":"parsing_exception","reason":"[multi_match] malformed query, expected [END_OBJECT] but found [FIELD_NAME]
The multi_match query must be located inside bool/must:
public function search_data_into_index($array)
{
$params = [
'index' => 'skills',
'type' => 'people',
'body' => [
'query' => [
'bool' => [
'must' => [
'multi_match' => [
'query' => 'react',
'fields' => [$array[2]],
'fuzziness' => 'AUTO',
]
],
'filter' => [
'geo_distance' => [
'distance' => '300m',
'location' => '-25, -49'
]
]
]
]
]
];
$response = $this->client->search($params);
print_r($response);
}
You need to combine multiple queries using boolean query
In JSON format your query will look like
{
"query": {
"bool": {
"must": {
"multi_match": {
"query": "react",
"fields": [$array[2]]
}
},
"filter": {
"geo_distance": {
"distance": "300m",
"location": [
"-25, -49"
]
}
}
}
}
}

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
]
]
]

Can't have a term and geo_distance_range in the same must filter

I have some data and I am trying to get all the results that have a certain month and are less than 1.6km from the target point. I am using the PHP client so my query looks like this.
$crimeSearch = [
'size' => 0,
'query' => [
'filtered' => [
'filter' => [
'bool' => [
'must' => [
'term' => [
'month' => $date,
],
'geo_distance_range' => [
'location' => [
'lat' => $lat,
'lon' => $lng,
],
'lt' => '1.6km',
],
],
],
],
],
],
'aggs' => [
'group_by_category' => [
'terms' => [
'field' => 'category',
],
],
],
];
I am currently seeing the following error:
query_parsing_exception: No query registered for [location]
My mapping looks like this:
"properties": {
"location": {
"type": "geo_point"
},
"category": {
"type": "string",
"index": "not_analyzed"
},
"month": {
"type": "string",
"index": "not_analyzed"
}
}
Now if I comment out either the term value or the geo_distance_range value from the must array then I get the correct results back. This error only occurs when they are both present.
Can anyone see what I wrong with my query?
I have tried moving the geo_distance_range into its own must block but this seems to bring back all results that match either of the the must filters and not them both.
If you need any more information please ask!
Thank you.
I do not know anything about PHP but If I try to convert equivalent ES json query then this might work. I guess you need to put every must clause in array like this
[
'size' => 0,
'query' => [
'filtered' => [
'filter' => [
'bool' => [
'must' => [
[
'term' => [
'month' => $date,
]
],
[
'geo_distance_range' => [
'location' => [
'lat' => $lat,
'lon' => $lng,
],
'lt' => '1.6km',
],
],
],
],
],
],
],
'aggs' => [
'group_by_category' => [
'terms' => [
'field' => 'category',
],
],
],
];
This is equivalent to
{
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"month": "June"
}
},
{
"geo_distance_range": {
"lt": "1.6km",
"location": {
"lat": 37.9174,
"lon": -122.305
}
}
}
]
}
}
}
}
}
Does this work?

Whats wrong with the Elastic Search PHP search query?

I've been trying to get the following JSON working in PHP Arrays but I don't seem to get any hits.
The JSON is as follows:
{
"query": {
"filtered": {
"query": {
"query_string": {
"query": "search"
}
}
}
},
"fields": [
"body",
"title",
"postDate",
"user",
"name"
],
"from": 0,
"size": 50,
"sort": {
"_score": {
"order": "asc"
}
},
"explain": true
}
And the PHP I managed to create is like this:
$docs = $client->search([
'index' => 'blog',
'type' => 'posts',
'body' => [
'query' => [
'filtered' => [
'query' => [
'query_string' => [
'query' => $search_query
]
]
]
],
'fields' => [
'body',
'title',
'postDate',
'user',
'name'
],
'from' => 0,
'size' => 50,
'sort' => [
'_score' => [
'order' => 'asc'
]
]
]
]);
It returns an response but no hits, even though it should (and it does in case of the JSON request)
What is going on here?
The post type wasn't required at all... I somehow thought it was. I used a tool called ElasticHQ to generate the JSON and i didn't realize it wasnt using Posts as a type.
Changed it to
$docs = $client->search([
'index' => 'blog',
'body' => [
'query' => [
'filtered' => [
'query' => [
'query_string' => [
'query' => $search_query
]
]
]
],
'fields' => [
'body',
'title',
'postDate',
'user',
'name'
],
'from' => 0,
'size' => 50,
'sort' => [
'_score' => [
'order' => 'asc'
]
]
]
]);

Categories