Elasticsearch Scoring Documents to be able to fetch specific number of document per page

I have an index as books, and the structure of the document is as follows:

{
  "category_ids": [1,2,3],
  "title": "Book Title",
  "description": "some long description",
  "entity_type": "regular",      //regular,featured,premium
  "attributes": {
    "attr1": {
      "value": 1
    },
    "attr2": {
      "value": 1
    },
    "attr3": {
      "value": 1
    }
  }
}

I have a basic search on this index as :

GET books/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "fields": ["title^2", "description"], 
            "query": "some book"
          }
        }
      ]
    }
  },
  "from": 0,
  "size": 30
}

With this query, the documents are ordered by the relevance well. The question is, I want to get a specific number of documents according to the entity_type field value per page.

Example 1:

I have 30 records for the first page; I need to get 8 featured books, 8 premium books, and 14 regular books.

Example 2:

If there is no match with featured but we have 4 matches with premium, in this case, on the first page, we will have 4 premium and 26 regular books.

Example 3:
With the query above, we have matched 300 books, and in this corpus, we have more than 40 premium books and 10 featured in total. We need to show 8 premium and 8 featured for each page. So, the number of records should be the following:

  1. page : 8 premium, 8 Featured, 16 Regular
  2. page : 8 premium, 2 Featured, 20 Regular
  3. page : 8 premium, 22 Regular
  4. page: 8 premium, 22 Regular
  5. page: 8 premium, 22 Regular
  6. page: 30 regular

So, I am trying to ask how I could achieve this without using separate queries per type?

I have already used multi-search. In the controller, I sent a multi-search for featured premium books. According to the result of that query, I just sent another query for regular books, merged the results, and returned them. However, this solution requires sequential requests to understand how many featured or premium records matched and how many regulars I need to fetch. I am looking for a more elegant solution with rescoring or script_scoring without a second request.

To control the results at this level I believe you will need to send 3 separate queries, one per category, through the multi search API. I know you stated that yoiu did not want to do that, but I am anot aware of any other way to get the result you are looking for.

Yes, currently, I'm using a multi-search and multiple-request solution. However, it ends with some latency. I just thought that we could achieve a solution with Script Scoring or Rescore. Unfortunately, I could not solve it. I am not certain if there is already an implemented solution for these types of problems besides script scoring and rescore. Or perhaps I have overlooked the solution using these technologies.