docs: def find(self, resource, req, sub_resource_lookup):
          """Find documents for resource."""
          args = getattr(req, 'args', request.args if request else {}) or {}
          source_config = config.SOURCES[resource]
  
          if args.get('source'):
              query = json.loads(args.get('source'))
              if 'filtered' not in query.get('query', {}):
                  _query = query.get('query')
                  query['query'] = {'filtered': {}}
                  if _query:
                      query['query']['filtered']['query'] = _query
          else:
              query = {'query': {'filtered': {}}}
  
          if args.get('q', None):
              query['query']['filtered']['query'] = _build_query_string(args.get('q'),
                                                                        default_field=args.get('df', '_all'),
                                                                        default_operator=args.get('default_operator', 'OR'))
  
          if 'sort' not in query:
              if req.sort:
                  sort = ast.literal_eval(req.sort)
                  set_sort(query, sort)
              elif self._default_sort(resource) and 'query' not in query['query']['filtered']:
                  set_sort(query, self._default_sort(resource))
  
          if req.max_results:
              query.setdefault('size', req.max_results)
  
          if req.page > 1:
              query.setdefault('from', (req.page - 1) * req.max_results)
  
          filters = []
          filters.append(source_config.get('elastic_filter'))
          filters.append(source_config.get('elastic_filter_callback', noop)())
          filters.append({'and': _build_lookup_filter(sub_resource_lookup)} if sub_resource_lookup else None)
          filters.append(json.loads(args.get('filter')) if 'filter' in args else None)
          filters.extend(args.get('filters') if 'filters' in args else [])
  
          if req.where:
              try:
                  filters.append({'term': json.loads(req.where)})
              except ValueError:
                  try:
                      filters.append({'term': parse(req.where)})
                  except ParseError:
                      abort(400)
  
          set_filters(query, filters)
  
          if 'facets' in source_config:
              query['facets'] = source_config['facets']
  
          if 'aggregations' in source_config and self.should_aggregate(req):
              query['aggs'] = source_config['aggregations']
  
          if 'es_highlight' in source_config and self.should_highlight(req):
              query_string = query['query'].get('filtered', {}).get('query', {}).get('query_string')
              highlights = source_config.get('es_highlight', noop)(query_string)
  
              if highlights:
                  query['highlight'] = highlights
                  query['highlight'].setdefault('require_field_match', False)
  
          source_projections = None
          if self.should_project(req):
              source_projections = self.get_projected_fields(req)
  
          args = self._es_args(resource, source_projections=source_projections)
          try:
              hits = self.elastic(resource).search(body=query, **args)
          except elasticsearch.exceptions.RequestError as e:
              if e.status_code == 400 and "No mapping found for" in e.error:
                  hits = {}
              elif e.status_code == 400 and 'SearchParseException' in e.error:
                  raise InvalidSearchString
              else:
                  raise
  
          return self._parse_hits(hits, resource)