code: def scan_aggs(search, source_aggs, inner_aggs={}, size=10):
      
      def run_search(**kwargs):
          s = search[:0]
          s.aggs.bucket('comp', 'composite', sources=source_aggs, size=size, **kwargs)
          for agg_name, agg in inner_aggs.items():
              s.aggs['comp'][agg_name] = agg
          return s.execute()
  
      response = run_search()
      while response.aggregations.comp.buckets:
          for b in response.aggregations.comp.buckets:
              yield b
          if 'after_key' in response.aggregations.comp:
              after = response.aggregations.comp.after_key
          else:
              after= response.aggregations.comp.buckets[-1].key
          response = run_search(after=after)
docs: Helper function used to iterate over all possible bucket combinations of
      ``source_aggs``, returning results of ``inner_aggs`` for each. Uses the
      ``composite`` aggregation under the hood to perform this.