def search(self, sketch_id, query_string, query_filter, query_dsl, indices, count=False, aggregations=None, return_fields=None, enable_scroll=False, timeline_ids=None):
    'Search ElasticSearch. This will take a query string from the UI\n        together with a filter definition. Based on this it will execute the\n        search request on ElasticSearch and get result back.\n\n        Args:\n            sketch_id: Integer of sketch primary key\n            query_string: Query string\n            query_filter: Dictionary containing filters to apply\n            query_dsl: Dictionary containing Elasticsearch DSL query\n            indices: List of indices to query\n            count: Boolean indicating if we should only return result count\n            aggregations: Dict of Elasticsearch aggregations\n            return_fields: List of fields to return\n            enable_scroll: If Elasticsearch scroll API should be used\n            timeline_ids: Optional list of IDs of Timeline objects that should\n                be queried as part of the search.\n\n        Returns:\n            Set of event documents in JSON format\n        '
    scroll_timeout = None
    if enable_scroll:
        scroll_timeout = '1m'
    if (not indices):
        return {'hits': {'hits': [], 'total': 0}, 'took': 0}
    if query_filter.get('events', None):
        indices = {event['index'] for event in query_filter['events'] if (event['index'] in indices)}
    query_dsl = self.build_query(sketch_id=sketch_id, query_string=query_string, query_filter=query_filter, query_dsl=query_dsl, aggregations=aggregations, timeline_ids=timeline_ids)
    search_type = 'query_then_fetch'
    if count:
        if ('sort' in query_dsl):
            del query_dsl['sort']
        try:
            count_result = self.client.count(body=query_dsl, index=list(indices))
        except NotFoundError:
            es_logger.error('Unable to count due to an index not found: {0:s}'.format(','.join(indices)))
            return 0
        METRICS['search_requests'].labels(type='count').inc()
        return count_result.get('count', 0)
    if (not return_fields):
        return self.client.search(body=query_dsl, index=list(indices), search_type=search_type, scroll=scroll_timeout)
    try:
        if self.version.startswith('6'):
            _search_result = self.client.search(body=query_dsl, index=list(indices), search_type=search_type, _source_include=return_fields, scroll=scroll_timeout)
        else:
            _search_result = self.client.search(body=query_dsl, index=list(indices), search_type=search_type, _source_includes=return_fields, scroll=scroll_timeout)
    except RequestError as e:
        root_cause = e.info.get('error', {}).get('root_cause')
        if root_cause:
            error_items = []
            for cause in root_cause:
                error_items.append('[{0:s}] {1:s}'.format(cause.get('type', ''), cause.get('reason', '')))
            cause = ', '.join(error_items)
        else:
            cause = str(e)
        es_logger.error('Unable to run search query: {0:s}'.format(cause), exc_info=True)
        raise ValueError(cause) from e
    METRICS['search_requests'].labels(type='all').inc()
    return _search_result
Search ElasticSearch. This will take a query string from the UI
together with a filter definition. Based on this it will execute the
search request on ElasticSearch and get result back.

Args:
    sketch_id: Integer of sketch primary key
    query_string: Query string
    query_filter: Dictionary containing filters to apply
    query_dsl: Dictionary containing Elasticsearch DSL query
    indices: List of indices to query
    count: Boolean indicating if we should only return result count
    aggregations: Dict of Elasticsearch aggregations
    return_fields: List of fields to return
    enable_scroll: If Elasticsearch scroll API should be used
    timeline_ids: Optional list of IDs of Timeline objects that should
        be queried as part of the search.

Returns:
    Set of event documents in JSON format
def search(self, sketch_id, query_string, query_filter, query_dsl, indices, count=False, aggregations=None, return_fields=None, enable_scroll=False, timeline_ids=None):
    'Search ElasticSearch. This will take a query string from the UI\n        together with a filter definition. Based on this it will execute the\n        search request on ElasticSearch and get result back.\n\n        Args:\n            sketch_id: Integer of sketch primary key\n            query_string: Query string\n            query_filter: Dictionary containing filters to apply\n            query_dsl: Dictionary containing Elasticsearch DSL query\n            indices: List of indices to query\n            count: Boolean indicating if we should only return result count\n            aggregations: Dict of Elasticsearch aggregations\n            return_fields: List of fields to return\n            enable_scroll: If Elasticsearch scroll API should be used\n            timeline_ids: Optional list of IDs of Timeline objects that should\n                be queried as part of the search.\n\n        Returns:\n            Set of event documents in JSON format\n        '
    scroll_timeout = None
    if enable_scroll:
        scroll_timeout = '1m'
    if (not indices):
        return {'hits': {'hits': [], 'total': 0}, 'took': 0}
    if query_filter.get('events', None):
        indices = {event['index'] for event in query_filter['events'] if (event['index'] in indices)}
    query_dsl = self.build_query(sketch_id=sketch_id, query_string=query_string, query_filter=query_filter, query_dsl=query_dsl, aggregations=aggregations, timeline_ids=timeline_ids)
    search_type = 'query_then_fetch'
    if count:
        if ('sort' in query_dsl):
            del query_dsl['sort']
        try:
            count_result = self.client.count(body=query_dsl, index=list(indices))
        except NotFoundError:
            es_logger.error('Unable to count due to an index not found: {0:s}'.format(','.join(indices)))
            return 0
        METRICS['search_requests'].labels(type='count').inc()
        return count_result.get('count', 0)
    if (not return_fields):
        return self.client.search(body=query_dsl, index=list(indices), search_type=search_type, scroll=scroll_timeout)
    try:
        if self.version.startswith('6'):
            _search_result = self.client.search(body=query_dsl, index=list(indices), search_type=search_type, _source_include=return_fields, scroll=scroll_timeout)
        else:
            _search_result = self.client.search(body=query_dsl, index=list(indices), search_type=search_type, _source_includes=return_fields, scroll=scroll_timeout)
    except RequestError as e:
        root_cause = e.info.get('error', {}).get('root_cause')
        if root_cause:
            error_items = []
            for cause in root_cause:
                error_items.append('[{0:s}] {1:s}'.format(cause.get('type', ), cause.get('reason', )))
            cause = ', '.join(error_items)
        else:
            cause = str(e)
        es_logger.error('Unable to run search query: {0:s}'.format(cause), exc_info=True)
        raise ValueError(cause) from e
    METRICS['search_requests'].labels(type='all').inc()
    return _search_result