I have a recommender that stores it's model in Elasticsearch. I want a query that return items that match "terms" in the model, but that also has business rules to include, exclude, and boost hits based on metadata stored in item fields.
Top all this off I want the hits to be filtered by dates for expire and available and if there are no hits based on the "should" clause, we want to fall back to sorting based on a numerical field (some popularity rank) that we add to items.
To recap, hits based on "should" get scores based on matching and nothing else, the "must"and "must_not" only act as inclusion or exclusion filters. If there is no match in "should" then the same rules apply to all items with a sortable field but they always return a score of 0. If no items have the sortable field that pass the "must" and "must_not" filters, then there will be no hits.
This should return:
- hits with scores, ranked by score. For a 'given number of hits these are ranked higher than any that come in via #2
- hits with score = 0 ranked by the sorting field, backfill the requested
size
if matches from #1 do not provide enough or return none. - the hits are allowed to be empty if nothing matches #1, and there is no sorting fallback ala #2
This query seems to do pretty much what I want, in hand tests. Does it seem well formed for the purpose? I am not an ES expert so would really appreciate opinions.
Thanks in advance
{
"size" : 20,
"from" : 0,
"query" : {
"bool" : {
"should" : [ {
"terms" : {
"purchase" : [ "iPad Pro" ]
}
}, {
"constant_score" : {
"filter" : {
"match_all" : { }
},
"boost" : 0
}
} ],
"must" : [ ],
"must_not" : [ ],
"filter" : [ {
"range" : {
"availableDate" : {
"lte" : "2018-12-20T01:42:19.550-08:00"
}
}
}, {
"range" : {
"date" : {
"gte" : "2017-12-20T01:42:19.450-08:00",
"lte" : "2017-12-26T01:42:19.450-08:00"
}
}
}, {
"range" : {
"expireDate" : {
"gte" : "2018-12-20T01:42:19.550-08:00"
}
}
} ],
"minimum_should_match" : 1
}
},
"sort" : [ {
"_score" : {
"order" : "desc"
}
}, {
"popRank" : {
"unmapped_type" : "double",
"order" : "desc"
}
} ]
}