Stop elastic search tokenizing a query - elasticsearch

I'm trying to filter out some documents in elastic search 8.4. The issue I'm having is something like this...
must_not: [
match: { ingredients: { query : 'peanut butter' } }
]
seems to break the query into 'peanut' and 'butter'. Then, documents which contain the ingredient 'butter' get incorrectly filtered. Is there a way to prevent this tokenizing without defining a custom analyzer? Or perhaps a different way to search to get that result?

If you don't want to filter documents with just "peanut" or "butter" you need to use the "and" operator. In this way only documents with "peanut butter" will be filtered.
{
"query": {
"bool": {
"must_not": [
{
"match": {
"ingredients": {
"query": "peanut butter",
"operator": "and"
}
}
}
]
}
}
}

Related

Elasticsearch exact search query

I'm using query string to search on documents in my index.
GET my_index/_search
{
"query": {
"bool": {
"must": [{
"query_string": {
"query": "table test",
"default_field": "table.name",
"default_operator":"AND"
}
}]
}
}
}
the problem is that it returns all additional strings that include search keywords.. I wanna to give strings that have exact phrase.
for example the documents table test 1 and table test 12 and table test are in my index. when I search table test, I wanna it just return table test.
I used term also, but it could not consider space charter between strings!
how can I handle this?
your mapping is generated by Elasticsearch, than for every text field there will be a corresponding .keyword field and hence
{
"query": {
"term": {
"table.name.kwyword": { // Note .keyword in the field name.
"value": "table test",
"boost": 1.0
}
}
}
if you don't have a .keyword field, then you have to create a keyword field and use term query that is used for exact or keyword searches.
You can use Match Phrase Query as Amit suggested in another answer.
Also, if you want to use only Query String type of query then you can give your query in double quotes as shown below:
GET my_index/_search
{
"query": {
"bool": {
"must": [{
"query_string": {
"query": "\"table test\"",
"default_field": "table.name",
"default_operator":"AND"
}
}]
}
}
}
Updated:
if you want to do exact match in entire field then you can go ahead with term query in elasticsearch:
{
"query": {
"term": {
"table.name.keyword": {
"value": "table test",
"boost": 1.0
}
}
}
}

How to use Wildcards in Elastic search query to skip some prefix values

"I am searching in a elasticsearch cluster GET request on the basis of sourceID tag with value :- "/A/B/C/UniqueValue.xml" and search query looks like this:-"
{
"query": {
"bool": {
"must": [
{
"term": {
"source_id": {
"value": "/A/B/C/UniqueValue.xml"
}
}
}
]
}
}
}
"How can i replace "/A/B/C" from any wildcard or any other way as i just have "UniqueValue.xml" as an input for this query. Can some please provide the modified search Query for this requirement? Thanks."
The following search returns documents where the source_id field contains a term that ends with UniqueValue.xml.
{
"query": {
"wildcard": {
"source_id": {
"value": "*UniqueValue.xml"
}
}
}
}
Note that wildcard queries are expensive. If you need fast suffix search, you could add a multi-field to your mapping which includes a reverse token filter. Then you can use prefix queries on that reversed field.

Query string query with keyword and text fields in the same search

Upgrading from Elasticsearch 5.x to 6.x. We make extensive use of query string queries and commonly construct queries which used fields of different types.
In 5.x, the following query worked correctly and without error:
{
"query": {
"query_string": {
"query": "my_keyword_field:\"Exact Phrase Here\" my_text_field:(any words) my_other_text_field:\"Another phrase here\" date_field:[2018-01-01 TO 2018-05-01]",
"default_operator": "AND",
"analyzer": "custom_text"
}
}
}
In 6.x, this query will return the following error:
{
"type": "illegal_state_exception",
"reason": "field:[my_keyword_field] was indexed without position data; cannot run PhraseQuery"
}
If I wrap the phrase in parentheses instead of quotes, the search will return 0 results:
{
"query": {
"query_string": {
"query": "my_keyword_field:(Exact Phrase Here)",
"default_operator": "AND",
"analyzer": "custom_text"
}
}
}
I guess this is because there is a conflict between the way the analyzer stems the incoming query and how the data is stored in the keyword field, but the phrase approach (my_keyword_field:"Exact Phrase Here") did work in 5.x.
Is this no longer supported in 6.x? And if not, what is the migration path and/or a good workaround?
It would be better to rephrase the query by using different type of queries available for different use cases. For example use term query for exact search on keyword field. Use range query for ranges etc.
You can rephrase query as below:
{
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "my_text_field:(any words) my_other_text_field:\"Another phrase here\"",
"default_operator": "AND",
"analyzer": "custom_text"
}
},
{
"term": {
"my_keyword_field": "Exact Phrase Here"
}
},
{
"range": {
"date_field": {
"gte": "2018-01-01",
"lte": "2018-05-01"
}
}
}
]
}
}
}

Not getting where data with filter (elastic search 6.4)

elasticsearch version: 6.4
Here is my current data:
I want to search for products which has Xbox in name. I am using the match keyword but that is not working.
Below is my elastic search query:
{
"query": {
"bool": {
"must": [
{
"match": {
"name": {
"query": "xbox"
}
}
},
{
"terms": {
"deep_sub": [
"Konsol Oyunları",
"Konsol Aksesuarları"
]
}
}
]
}
},
"from": 0,
"size": 50
}
Whenever you face such kind of issues, try breaking down the query. You have Match Query and Term Query. Run both of them individually and see what's not working.
From what I understand, looks like your field deep_sub is of text type and this would mean Term Query is not returning results.
You would need to create its sibling equivalent using keyword type and then run Term Query on it for exact matches.
From the above link we have the below info:
Keyword fields are only searchable by their exact value.
If you do not control the mapping, meaning if your mapping if of dynamic type, then you must have its sibling equivalent keyword field available which would be deep_sub.keyword
You can check by running GET <your_index_name>/_mapping
Your query would then be as follows:
POST <your_index_name>/_search
{
"query":{
"bool":{
"must":[
{
"match":{
"name":{
"query":"xbox"
}
}
},
{
"terms":{
"deep_sub.keyword":[ <----- Change This
"Konsol Oyunları",
"Konsol Aksesuarları"
]
}
}
]
}
},
"from":0,
"size":50
}
Let me know if this helps!

multi_match fuzzy query across multiple fields

I am working to match a 'term' to multi fields (or _all field)
I want to do a fuzzy match on cross_fields but it is not supported.
any ideas how to do it or any other ways to do it ?
query: {
multi_match: {
query: term,
type: "cross_fields",
fields: ['_all']
}
}
when trying the solution here
ElasticSearch multi_match query over multiple fields with Fuzziness
I get this error
[parsing_exception] Fuziness not allowed for type [cross_fields], with
{ line=1 & col=128 }
elasticsearch version 5.0
edit:
here is the query I am building
bool: {
must: [
{
fuzzy: {
_all: term
}
},
{
fuzzy: {
"location.country": country
}
},
{
fuzzy: {
"location.city": city
}
}
]
}
cross_fields works by searching the term on your multiple fields. Since fuzziness isn't supported for cross_fields you have to write the query in a different way.
One possible is: implement your own "cross_fields" with shoulds and add there the fuzziness.
Say your term is: "term1 term2", you can split by word boundary (Regex \b) then should them in this form:
{
{
"query": {
"bool": {
"should": [{
"match": {
"field1": "term",
"fuzziness": 1
}
},{
"match": {
"field1": "term",
"fuzziness": 1
}
},{
"match": {
"field2": "term1",
"fuzziness": 1
}
},{
"match": {
"field2": "term12",
"fuzziness": 1
}
}
]
}
}
}
}
This is probably less the optimal if you have many fields, the query will become a cartesian product of the terms and fields.
Important note You're using _all field which is one field. which all other fields are indexed into. Maybe you don't even need cross_fields?

Resources