'Solr edismax query parser syntax.
:param query_s: a query string of search terms (e.g. - sales quarterly);
Currently the search will perform an OR boolean search for all terms (split on whitespace), against a whitelist
of search_fields.'

def search_entities(self, query_s, limit=100, offset=0, **filters):

    search_fields = ('originalName', 'originalDescription', 'name', 'description', 'tags')
    sources = filters.get('sources', [])
    (default_entity_types, entity_types) = self._get_types_from_sources(sources)
    try:
        query_s = query_s.replace('{', '\\{').replace('}', '\\}').replace('(', '\\(').replace(')', '\\)').replace('[', '\\[').replace(']', '\\]')
        params = self.__params
        search_terms = [term for term in query_s.strip().split()]
        query_clauses = []
        user_filters = []
        source_type_filter = []
        for term in search_terms:
            if (':' not in term):
                if (('sql' in sources) or ('hive' in sources) or ('impala' in sources)):
                    if ('.' in term):
                        (parent, term) = term.rsplit('.', 1)
                        user_filters.append(('parentPath:"/%s"' % parent.replace('.', '/')))
                query_clauses.append('OR'.join([('(%s:*%s*)' % (field, term)) for field in search_fields]))
            else:
                (name, val) = term.split(':')
                if val:
                    if (name == 'type'):
                        term = ('%s:%s' % (name, val.upper().strip('*')))
                        default_entity_types = entity_types
                    user_filters.append((term + '*'))
        filter_query = '*'
        if query_clauses:
            filter_query = 'OR'.join([('(%s)' % clause) for clause in query_clauses])
        user_filter_clause = ('AND    '.join([('(%s)' % f) for f in user_filters]) or '*')
        source_filter_clause = 'OR'.join([('(%s:%s)' % ('type', entity_type)) for entity_type in default_entity_types])
        if ('s3' in sources):
            source_type_filter.append('sourceType:s3')
        elif (('sql' in sources) or ('hive' in sources) or ('impala' in sources)):
            source_type_filter.append('sourceType:HIVE    OR    sourceType:IMPALA')
        filter_query = ('%s    AND    (%s)    AND    (%s)' % (filter_query, user_filter_clause, source_filter_clause))
        if source_type_filter:
            filter_query += ('    AND    (%s)' % 'OR    '.join(source_type_filter))
        source_ids = get_cluster_source_ids(self)
        if source_ids:
            filter_query = (((source_ids + '(') + filter_query) + ')')
        params += (('query', filter_query), ('offset', offset), ('limit', NAVIGATOR.FETCH_SIZE_SEARCH.get()))
        LOG.info(params)
        response = self._root.get('entities', headers=self.__headers, params=params)
        response = list(islice(self._secure_results(response), limit))
        return response
    except RestException as e:
        LOG.error(('Failed    to    search    for    entities    with    search    query:    %s' % query_s))
        if (e.code == 401):
            raise NavigathorAuthException(_('Failed    to    authenticate.'))
        else:
            raise NavigatorApiException(e)
