Elasticsearch wildcard search: when I add space to a query everything falls apart - elasticsearch

I have a English dictionary Index, I search fields with the following JSON
GET /words/_search
{
"from": 0,
"size": 10,
"query": {
"bool": {
"filter": [
{
"bool": {
"should": [
{
"query_string": {
"default_field": "text",
"query": "*orhan*"
}
}
]
}
}
]
}
},
"track_total_hits": true
}
My query purpose is to get all records if they include orhan name, and after running the query I get the results as expected;
_id
_idex
_score
_type
text
B6F1eoQBu3ncIuw4CyKL
words
0.0
_doc
orhan
cKN5eoQBu3ncIuw4JgxK
words
0.0
_doc
vorhand
drDzzYQBu3ncIuw4vn10
words
0.0
_doc
orhan second word
I modify my query and I try the search orhan s but everything falls apart, the whole 54665 records were shown to me.
###
"bool": {
"should": [
{
"query_string": {
"default_field": "text",
"query": "*orhan s*" // <- modified
}
###
I can't add the whole response :) But I can provide,
Response of total value:
"total": {
"value": 54665,
"relation": "eq"
},
My response shouldn't include the whole record just related records shown to me
Query: "query": "*orhan s*"
Response:
_id
_idex
_score
_type
text
drDzzYQBu3ncIuw4vn10
words
0.0
_doc
orhan second word

That's because the default operator is an OR, so you are catching all the words finishing with orhan OR starting with s.
You can change the operator:
GET /words/_search
{
"from": 0,
"size": 10,
"query": {
"bool": {
"filter": [
{
"bool": {
"should": [
{
"query_string": {
"default_field": "text",
"query": "*orhan s*",
"default_operator": "AND"
}
}
]
}
}
]
}
},
"track_total_hits": true
}
Or add the operator to the query directly:
GET /test_words/_search
{
"from": 0,
"size": 10,
"query": {
"bool": {
"filter": [
{
"bool": {
"should": [
{
"query_string": {
"default_field": "text",
"query": "*orhan AND s*"
}
}
]
}
}
]
}
},
"track_total_hits": true
}

Related

Filter with querystring in elasticsearch

I send this query and it works fine. It returns filtered data:
{
"query": {
"bool": {
"filter": [
{
"match": {
"lang": "en"
}
}
]
}
},
"size": 10,
"from": 0,
"sort": []
}
If I want to search with searchstring then it workst fine too:
{
"query": {
"query_string": {
"query": "big size"
}
},
"size": 10,
"from": 0,
"sort": []
}
But I can't get data from elastic by filter and searchstring together:
{
"query": {
"query_string": {
"query": "big size"
},
"bool": {
"filter": [
{
"match": {
"lang": "en"
}
}
]
}
},
"size": 10,
"from": 0,
"sort": []
}
I receive next error:
Error 400.
{"error":{"root_cause":[{"type":"parsing_exception","reason":"[query_string] malformed query, expected [END_OBJECT] but found [FIELD_NAME]","line":1,"col":76}],"type":"parsing_exception","reason":"[query_string] malformed query, expected [END_OBJECT] but found [FIELD_NAME]","line":1,"col":76},"status":400}
Your query needs to be restructured as shown below.
Query:
{
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "big size"
}
}
],
"filter": [
{
"match": {
"lang": "en"
}
}
]
}
},
"size": 10,
"from": 0,
"sort": []
}

Elasticsearch Ranking on aggregation based on AND and OR

I have a query with multiple keywords with an aggregation on author ID.
I want the ranking to be based on combining must and should.
For example for query 'X', 'Y' the authors containing both 'X' and 'Y' in the document field should be ranked higher, followed by authors who have either 'X' or 'Y'.
Doing each of them (AND/OR) is easy, I need the idea/direction how to achieve both in one ES query.
The current query I have for both X and Y is:
GET /docs/_search
{
"size": 0,
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "X",
"fields": [
"fulltext"
],
"default_operator": "AND"
}
},
{
"query_string": {
"query": "Y",
"fields": [
"fulltext"
],
"default_operator": "AND"
}
}
]
}
},
"aggs": {
"search-users": {
"terms": {
"field": "author.id.keyword",
"size": 200
},
"aggs": {
"top-docs": {
"top_hits": {
"size": 100
}
}
}
}
}
}
Changing must to should change it to OR but I want the combination of both ranking authors with must a higher ranking in aggregation.
The usual way of boosting results is by adding a should clause looking for both terms, like this.
GET /docs/_search
{
"size": 10,
"query": {
"bool": {
"should": [
{
"match": {
"fulltext": "X Y",
"operator": "AND"
}
}
],
"must": [
{
"match": {
"fulltext": "X Y",
"operator": "OR"
}
}
]
}
},
"aggs": {
"search-users": {
"terms": {
"field": "author.id.keyword",
"size": 200
},
"aggs": {
"top-docs": {
"top_hits": {
"size": 100
}
}
}
}
}
}

ElasticSeach combine multi_match and match_phrase

I use ES 7, I want to search over multi fields, but on this field (title) must be shown firstly if it matches exactly. For now I tried :
{
"query": {
"bool": {
"must": {
"bool": {
"should": [
{
"match_phrase": {
"titre": {
"query": "test",
"boost": "20"
}
}
},
{
"multi_match": {
"fields": ["titre", "description^4", "subtitle^3"],
"query": "test",
"type": "most_fields"
}
}
]
}
}
}
}
}
It works, but I would like to order the match_phrase before other results.
The idea is the user type the exact phrase of a title, this result will appear before other based on multi_match.
Is it possible ?

Elastic Search Query to get results for multiple keywords(i.e Country name)

Key String will be like
"india,singapore" without quotes.
How to split and search the keyword
Expected result will be match the country with india or singapore.
So far i tried..
{
"_source": "country_name",
"query": {
"bool": {
"must": [
{
"term": {
"country_name.keyword": "india,singapore"
}
}
],
"must_not": [],
"should": []
}
},
"from": 0,
"size": 10,
"sort": [],
"aggs": {}
}
But it will showing only those content have match the exact key string "india,singapore"
you can use terms query in place of term query like below:
{
"_source": "country_name",
"query": {
"bool": {
"must": [
{
"terms": {
"country_name.keyword": ["india","singapore"]
}
}
]
}
},
"from": 0,
"size": 10
}

elasticsearch must query combine OR?

I have been trying to use a must query with bool but I am failing to get the results.
In pseudo-SQL:
SELECT * FROM info WHERE (ulevel= '1.3.10' or ulevel= '1.3.6') AND (#timestamp between '2017-06-05T07:00:00.000Z' and '2017-06-05T07:00:00.000Z')
Here is what I have:
"query": {
"bool": {
"must": [
{
"query_string": {
"default_field": "_all",
"query": "*"
},
"range": {
"#timestamp": {
"from": "2017-06-05T07:00:00.000Z",
"to": "2017-06-05T07:20:00.000Z"
}
},
"bool": {
"should": [
{"term": { "ulevel": "1.3.10"}},
{"term": { "ulevel": "1.3.6"}}
]
}
}
]
}
}
Does anyone have a solution?
Thank you so much.
You can use terms query for the first part and the range query for the second part
GET _search
{
"query": {
"bool": {
"must": [
{
"terms": {
"ulevel": [
"1.3.10",
"1.3.6"
]
}
},
{
"range": {
"#timestamp": {
"gte": "2017-06-05T07:00:00.000Z",
"lte": "2017-06-05T07:20:00.000Z"
}
}
}
]
}
},
"from": 0,
"size": 20
}
Some Notes :
Filters documents that have fields that match any of the provided terms (not analyzed)
Also you can use some date spesific formulation with rage filter. Please check the range query page https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html#ranges-on-dates more information.
Update:
Added from and size for comment question.

Resources