# Return popular docs if no hits

**URL:** <https://discuss.elastic.co/t/return-popular-docs-if-no-hits/25073>\
**Category:** Elasticsearch\
**Created:** [July 7, 2015, 6:39pm UTC](https://discuss.elastic.co/t/return-popular-docs-if-no-hits/25073 "2015-07-07T18:39:29Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![pferrel](https://avatars.discourse-cdn.com/v4/letter/p/59ef9b/32.png) [@pferrel](https://discuss.elastic.co/u/pferrel)\
**Post date:** [July 7, 2015, 6:39pm UTC](https://discuss.elastic.co/t/return-popular-docs-if-no-hits/25073/1 "2015-07-07T18:39:29Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![nik9000](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/nik9000/32/44947_2.png) [@nik9000](https://discuss.elastic.co/u/nik9000)\
**Post date:** [July 7, 2015, 7:20pm UTC](https://discuss.elastic.co/t/return-popular-docs-if-no-hits/25073/2 "2015-07-07T19:20:07Z")

</div>

> [@pferrel](#):
>
> 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.

---

<div class="post-metadata">

**Author:** ![pferrel](https://avatars.discourse-cdn.com/v4/letter/p/59ef9b/32.png) [@pferrel](https://discuss.elastic.co/u/pferrel)\
**Post date:** [July 7, 2015, 7:34pm UTC](https://discuss.elastic.co/t/return-popular-docs-if-no-hits/25073/3 "2015-07-07T19:34:42Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [July 6, 2017, 12:03am UTC](https://discuss.elastic.co/t/return-popular-docs-if-no-hits/25073/4 "2017-07-06T00:03:03Z")

</div>


