Elasticsearch Query NOT searching in the specified fields - elasticsearch

I am struggling with an elasticsearch query. In the fields option, we have specified '*' which means it should look in all fields as well as given the higher weights to a few fields. But it isn't working as it should.
This query was written by my colleague, it'd be great if you could explain it as well as point out the solution. Here's my query:
{
"query": {
"bool": {
"must": [
{
"simple_query_string": {
"query": "Atoms for Peace",
"default_operator": "AND",
"flags": "PREFIX|PHRASE|NOT|AND|OR|FUZZY|WHITESPACE",
"fields": [
"*",
"systemNumber^5",
"global_search",
"objectType^2",
"partTypes.text",
"partTypes.id",
"gs_am_people^2",
"gs_am_person^2",
"gs_am_org^2",
"gs_title^2",
"_currentLocation.displayName",
"briefDescription",
"physicalDescription",
"summaryDescription",
"_flatPersonsNameId",
"_flatPeoplesNameId",
"_flatOrganisationsNameId",
"_primaryDate",
"_primaryDateEarliest",
"_primaryDateLatest"
]
}
}
]
}
}

Your query is fine but it will not work on field with "nested" data type.
From doc
Searching across all eligible fields does not include nested documents. Use a nested query to search those documents.
You need to use nested query
{
"query": {
"bool": {
"minimum_should_match": 1,
"should": [
{
"simple_query_string": {
"query": "Atoms for Peace",
"default_operator": "AND",
"flags": "PREFIX|PHRASE|NOT|AND|OR|FUZZY|WHITESPACE",
"fields": [
"*",
"systemNumber^5",
"global_search",
"objectType^2",
"partTypes.text",
"partTypes.id",
"gs_am_people^2",
"gs_am_person^2",
"gs_am_org^2",
"gs_title^2",
"_currentLocation.displayName",
"briefDescription",
"physicalDescription",
"summaryDescription",
"_flatPersonsNameId",
"_flatPeoplesNameId",
"_flatOrganisationsNameId",
"_primaryDate",
"_primaryDateEarliest",
"_primaryDateLatest"
]
}
},
{
"nested": {
"path": "record",
"query": {
"simple_query_string": {
"query": "Atoms for Peace",
"default_operator": "AND",
"flags": "PREFIX|PHRASE|NOT|AND|OR|FUZZY|WHITESPACE",
"fields": [
"*"
]
}
}
}
}
]
}
}
}

Related

How to boost exact match on multi match in elastic search

I have several documents with a field name title contain value like foo bar and foo:bar.
I'm trying to boost an exact match foo:bar documents and sort the result according to the score.
Here is my attempt, any help would be appreciated.
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "",
"fields": [
"title",
]
}
}
],
"should": [
{
"multi_match": {
"query": "",
"fields": [
"title",
]
"type": "phrase"
"boost": 20
}
}
],
}
}

Querying fields with AND in ElasticSearch

In my ElasticSearch document index I have a property type like
type= LOCATION | PERSON | TIME
and a text field that represents the whole document.
To search for types like LOCATION and a specific text like `Mountain View" I do like
doc.text:Mountain View AND doc.type:LOCATION
If I want to do a OR query I would use instead the query_string approach like
"query": {
"query_string": {
"query": "entity.text: (Mountain View OR Menlo Park) AND entity.type:LOCATION"
}
}
This works as well. To do AND queries, like searching for item.text having both "Mountain View" and "Menlo Park" for a item.type=LOCATION, it does not work doing like
"query": {
"query_string": {
"query": "entity.text: (California AND Nevada) AND entity.type:LOCATION"
}
}
Other attempts were:
Using bool clause with should like:
{
"query": {
"bool": {
"should": [
{ "match": { "text": "Menlo Park" }},
{ "match": { "text": "Mountain View" }}
]
}
}
}
Using cross-fields with multi_match
"query": {
"multi_match": {
"query": "California Nevada",
"type": "cross_fields",
"operator": "AND",
"fields": [
"text"
]
}
}
Another approach was using must with the latter (in this case omitting the type by the way):
{
"query": {
"bool": {
"must": [
{
"multi_match" : {
"query": "Nevada",
"type": "cross_fields",
"fields": [ "text"],
}
},
{
"multi_match" : {
"query": "California",
"type": "cross_fields",
"fields": [ "text" ]
}
}
]
}
}
}
but it returns no results neither. Note that in the last case using should instead of must will produce an OR query that will work ok.
So how to perform an AND query on the same field text to match multiple values like California and Nevada?
If I understood the question right, I would do the following:
{
"query": {
"bool" : {
"must": [
"match" : {
"text" : {
"query" : "California Nevada",
"operator" : "and"
}
}
]
}
}
}
Documentation
Hope it helps!

how to perform partial match elasticsearch

i want to perform both exact match and partial match. for example, "Alize", so if i type "Ali" it should return the result of "Alize" as well. for this case i only can return the result if i type exact word "Alize".
POST /ecommerce/_search
'{
"query": {
"multi_match": {
"fields": [
"name"
],
"operator": "AND",
"query": "Ali*"
}
},
"size": 20,
"stored_fields": [
"uid",
"_source"
]
}`
You can use querystring query as following
"query": {
"query_string": {
"query": "Ali*",
"fields": ["name"]
}
}
Or use wildcard
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{"query": {"wildcard": {"name": {"value": "Ali*"}}}},
]
}
}
}
}
Wildcard document
This solutions work perfectly for django_elasticsearch_dsl
search_keyword = search_keyword + "*"
query = document_class.search().query(
{
"query_string": {
"query": search_keyword,
"fields": ["name", "code"]
}
}

Elastic : search two terms, one on _all, other one on a field

I would like to mix a search on a whole document (eg "developer") and a search on some field for another term (eg "php").
I can do each search separately but I can't mix them.
Here my example (simplified to show only my issue) :
{
"query": {
"function_score": {
"query": {
"match": {
"_all": "developer"
},
"multi_match": {
"query": "php",
"fields": [
"skills.description",
"skills.description",
"skills.details"
],
"operator": "or",
"type": "most_fields"
}
}
}
}
If I run this example I have an error :
Parse Failure [Failed to parse source
Is there a way to search on both _all and specific fields with two terms?
Thanks.
Yes, you're almost there, you need to combine them into a bool/must query:
{
"query": {
"function_score": {
"query": {
"bool": {
"must": [
{
"match": {
"_all": "developer"
}
},
{
"multi_match": {
"query": "php",
"fields": [
"skills.description",
"skills.description",
"skills.details"
],
"operator": "or",
"type": "most_fields"
}
}
]
}
}
}
}
}

ElasticSearch: how to search for %like% values in a field

I have a search query (in Postman/Chrome) that returns a list of companies, but I need to filter them out for a specific pattern. What filter do I use and how to do it?
I need to filter query result for company_id LIKE %50%
Her is what I run:
{
"fields": [
"company_id"
],
"query": {
"bool": {
"must": [
{"term": {"app.raw": "AAA"}},
{"wildcard": {"cat.raw": "RS"}}
],
"must_not": [],
"should": []
}
},
"from": 0,
"size": 5,
"sort": [],
"facets": {}
}
I get back something like:
"hits": [
{
...
"fields": {
"company_id": [
"745"
]
}
},
{
...
"fields": {
"company_id": [
"5056"
]
}
},
{
...
"fields": {
"company_id": [
"7765"
]
}
},
{
...
"fields": {
"company_id": [
"5044"
]
}
},
{
...
"fields": {
"company_id": [
"501"
]
}
First of all I am not fully sure what issue you are facing. You are not getting correct/expected result? You need to include the mapping you have used because the query will depend on it.
Wildcard searches are heavy. If you want to do partial matching search (equivalent of %like%)You can use ngram token filter in your analyzer and do term search. It will take care of matching partial string.
You can define an analyzer like
{
"settings":{
"analysis":{
"analyzer":{
"Like":{
"type":"custom",
"tokenizer":"keyword",
"filter":[ "lowercase", "ngram" ]
}
},
"filter":{
"ngram":{
"type":"ngram",
"min_gram":2,
"max_gram":15
}
}
}
}
}
And define in your mapping for cat.raw the analyzer "Like" defined above.
If you have used the ngram in your analyzer then You can change the query part to something simple term query like
"query": {
"bool": {
"must": [
{"term": {"app.raw": "AAA"}},
{"term": {"cat.raw": "RS"}}
],
"must_not": [],
"should": []
}
}
EDIT: updated answer based on comment
Ok now it is clear what you want to do.
One way is to define company_id As string in your mapping and use prefix query
"query": {
"bool": {
"must": [
{"term": {"app.raw": "AAA"}},
{"term": {"cat.raw": "RS"}},
{"prefix":{"company_id": "50"}}
],
"must_not": [],
"should": []
}
}
Another alternative could be to use edgengram in your analyzer for company_id and use term filter/query.
Note: for search in "cat.raw" it is still better to use the term query with analyzer having ngram instead of the wildcard query.

Resources