I have a query that searches given terms in a text field by given time interval. I want to add phrase match to this query how can I add; for example I'll look for "has parti" as a phrase but the text shouldn't have "ahmet" word. How can I do this; the code is here;
{
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"terms": {
"text": [
"has",
"parti"
]
}
},
{
"range": {
"date": {
"gt": "2015-08-27",
"lte": "2015-08-28"
}
}
}
]
}
}
}
}
}
Elasticsearch provides Phrase matching, but I don't think you can use it in the filter, or at least I didn't manage to have it working. I have a solution, with match_phrase
in the query
, together with the condition that text
does not contain ahmet
, while the time interval stays in the filter
. Check if it's good enough for you.
{
"query": {
"filtered": {
"query": {
"bool": {
"must": [
{
"match_phrase": {
"text": "has parti"
}
}
],
"must_not": [
{
"match": {
"text": "ahmet"
}
}
]
}
},
"filter": {
"bool": {
"must": [
{
"range": {
"date": {
"gt": "2015-08-27",
"lte": "2015-08-28"
}
}
}
]
}
}
}
}
}
By the Way, your date
looks like being mapped as string, because otherwise your request would fail with
ElasticsearchParseException[failed to parse date field [2015-08-22], tried both date format [date_time], and timestamp number]; nested: IllegalArgumentException[Invalid format: \"2015-08-22\" is too short]; }]
I suggest using a proper mapping, but that's not really related to your question
UPDATE:
Just came back to add that we did the right thing: filters are not for full-text search
UPDATE:
Since the filtered query has been deprecated, in new versions the query should be rewritten in order to move the filter inside the bool query:
{
"query": {
"bool": {
"must": [{
"match_phrase": {
"text": "has parti"
}
}],
"must_not": [{
"match": {
"text": "ahmet"
}
}],
"filter": {
"bool": {
"must": [{
"range": {
"date": {
"gt": "2015-08-27",
"lte": "2015-08-28"
}
}
}]
}
}
}
}
}