Querying fields with AND in ElasticSearch - 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!

Related

Elastic Search : Search keyword results of a specific category

I'm trying to build a query where I'm trying to search for names of people of a specific country. If I provide input as John and USA, I should only find results of people by the name John (by the property : name) from USA (by the property : country) and results from other countries shouldn't appear in the results.
What I have tried :
"query": {
"bool": {
"should": [
{
"multi_match": {
"query": "John",
"fields": ["username", "first_name", "last_name"],
"fuzziness": "AUTO",
"minimum_should_match": "50%"
}
}
],
"filter": [
{
"match": {
"country": "USA"
}
},
{
"match": {
"is_citizen": true
}
}
]
}
}
With the above query the problem I'm seeing is that the results also show people **who don't have their name as John but are from USA
**.
Expectation : To filter results of given keyword specific to given country.
Instead of using should you need to use must clause in your name query.
Below query should give you expected results. refer boolean query official doc to understand the difference with examples.
"query": {
"bool": {
"must": [ --> note `must` here
{
"multi_match": {
"query": "John",
"fields": ["username", "first_name", "last_name"],
"fuzziness": "AUTO",
"minimum_should_match": "50%"
}
}
],
"filter": [
{
"match": {
"country": "USA"
}
},
{
"match": {
"is_citizen": true
}
}
]
}
}
You are using should clause thats why it is not working. You can use must insted of should and it will resolved your issue.
You can use "type":"phrase_prefix" to match Jo with John.
You can change your query as shown below and it will work:
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "John",
"fields": ["username", "first_name", "last_name"],
"type":"phrase_prefix",
"minimum_should_match": "50%"
}
}
],
"filter": [
{
"match": {
"country": "USA"
}
},
{
"match": {
"is_citizen": true
}
}
]
}
}

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 ?

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

Relevance by type on same field in elasticsearch

Is there any way to boost search results on same field depending on type?
My basic boosting is something like:
GET _search
{
"query": {
"simple_query_string": {
"query": "mangan",
"fields":["_all", "title^6"]
}
}
}
But for some other documents I want title to be less important, so I tried to prefix it with type:
GET _search
{
"query": {
"simple_query_string": {
"query": "mangan",
"fields":[
"_all",
"DocumentationPage.title^6",
"DocumentationPage.title^6"]
}
}
}
But then it does not boost at all. As a last resort I could use Funcsion/Script Score bu would like to avoid it.
For sake of example, assume that document contains just title field.
A simple way to achieve this is re-writing the query in the OP as a dis-max query.
Example for elasticsearch 5.x:
{
"query": {
"dis_max": {
"queries": [
{
"simple_query_string": {
"fields": [
"_all"
],
"query": "mangan"
}
},
{
"bool": {
"filter": {
"type": {
"value": "DocumentationPage"
}
},
"must": [
{
"simple_query_string": {
"fields": [
"title^6"
],
"query": "mangan"
}
}
]
}
}
]
}
}
}

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

Resources