Reputation: 3064
I have an index that contains three string fields "user_id", "headline" and "note". I want to search for documents that A) belong to a specific user and B) have a text match in either the "headline" or "notes". I am using AWS Elasticsearch 7.4 and I haven't done any schema or mapping - I simply started to post documents against the index.
What I tried was this:
query = {
"bool": {
"should": [
{"match": {"headline": search_text}},
{"match": {"note": search_text}}
],
"must": {"match": {"user_id": user_id}}
}
}
This works but it finds documents where search text does not match either "headline" or "note". Basically I need a boolean query saying: user_id = :user_id AND (headline = :search_text OR note = :search_text)
Upvotes: 2
Views: 198
Reputation: 32386
Due to in-proper use of boolean clause your existing query not working and its working according to Refer https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html for more details on boolean query
user_id = :user_id OR (headline = :search_text OR note = :search_text)
Complete working example tested in my local with sample docs:
Indexed three sample docs with defining mapping:
{
"user_id" : "1",
"headline" : "today",
"note" : "today"
}
{
"user_id" : "1",
"headline" : "tomorrow",
"note" : "today"
}
{
"user_id" : "1",
"headline" : "tomorrow",
"note" : "tomorrow"
}
According to your condition, when searching for user_id
1
and text
= today
only doc 1 and 2 must be returned.
Proper search query
{
"query": {
"bool": {
"must": [
{
"match": {
"user_id": "1"
}
},
{
"multi_match": {
"query": "today",
"fields": [
"headline",
"note"
]
}
}
]
}
}
}
Search result
"hits": [
{
"_index": "booleanaws",
"_type": "_doc",
"_id": "1",
"_score": 1.1143606,
"_source": {
"user_id": "1",
"headline": "today",
"note": "today"
}
},
{
"_index": "booleanaws",
"_type": "_doc",
"_id": "2",
"_score": 0.603535,
"_source": {
"user_id": "1",
"headline": "tomorrow",
"note": "today"
}
}
]
Upvotes: 2
Reputation: 710
The following query should work for : user_id = :user_id AND (headline = :search_text OR note = :search_text)
query = {
"bool": {
must:[
{
"match": {"user_id": user_id}
},
"bool":{
"should":[
{"match": {"headline": search_text}},
{"match": {"note": search_text}}
]
}
]
}
}
Upvotes: 0