Return popular docs if no hits

I'd like my query to return popular documents if the rest of the query has no hits.

I'm periodically updating a double value for every doc, with it's popularity magnitude so the "popularity" field is always available.

My query will include boosts and filters based on various fields and so looks like this (using example data):

POST /index/docs/_search
{
   "size": 10,
   "query": {
      "bool": {
         "should": [
            {"terms": {“title": ["phone"]}},
            {"terms": {“text": [“ipad”, “iphone”, “galaxy"], boost: 1.5}}
         ],
         "must": [
            {"terms": {"category": ["electronics"]}}
         ]
      }
   }
}

I need to return the most popular items if none are hit with the should clause but would still like the must to apply so popular items obey the category filter in the example.

Most examples I've seen boost the item's score by popularity and that's not at all what I want, popularity is for backfill only.

Any ideas?

I'd run a second query for popularity if you don't get any hits on the first one. You could use the multi search api if that doesn't float your boat.

I'd just send it the bool query with the should clause stripped out and wrap it in a function score query to score with popularity.

You can even cache the results of the popularity queries if you find them to be slow but I don't expect them to be.

On stackoverflow @keety suggested the following, which uses the populatiry as a secondary sort on all items. This seems to do what I need except the constant score/matchall needs to be subject to the must clause. I'm just learning the ES JSON API so examples really help.

{
   "size": 10,
   "query": {
      "bool": {
         "should": [
            {
               "bool": {
                  "should":[
                     {"terms": {“title": ["phone"]}},
                     {"terms": {“text": [“ipad”, “iphone”, “galaxy"], boost: 1.5}}
                  ],
                  "must": [
                     {"terms": { "category": [ "electronics" ]}}
                  ]
               }
            },
            {
               "constant_score": {
                  "filter": {
                     "match_all": {}
                  },
                  "boost": 0
               }
            }
         ],
         "minimum_should_match": 1
      }
   },
   "sort": [
      {
         "_score": {
            "order": "desc"
         }
      },
      {
         "popularity": {
            "unmapped_type": "double"
         }
      }
   ]
}