def get_count(self): try: return self.es.count(self.get_query(), self.get_filters()) except queryparser.QueryParseError: # try queries one by one for i, q in enumerate(self.get_queries()): queryparser.parse_to_terms(q.query, context=(q.declared_label or i+1)) # if error wasn't raised yet, re-raise original raise
def filter_query(self, query: str): """ Filter a queryset using a querystring. This is different from query(), as it will not be able to generate highlights or scores. It is quicker, however. """ query_term = queryparser.parse_to_terms(query) return self._copy(filters=self.filters + (query_term.get_dsl(),))
def highlight_article(self, aid, query): query = queryparser.parse_to_terms(query).get_dsl() highlight_opts = { "highlight_query": query, "number_of_fragments": 0 } body = { 'filter': build_filter(ids=aid), 'highlight': { "fields": { "text": highlight_opts, "headline": highlight_opts, "byline": highlight_opts } } } r = self.search(body, fields=[]) try: hl = r['hits']['hits'][0]['highlight'] return {f: hl[f][0] for f in hl} except KeyError: log.exception("Could not get highlights from {r!r}".format(**locals()))
def query(self, query: str) -> "ESQuerySet": """ Use a query string to query the final result. If you do not need scoring, use filter_query. @param query: query in Lucene syntax """ query_dsl = queryparser.parse_to_terms(query) return self._copy(_query=query_dsl)
def build_body(query=None, filters={}, query_as_filter=False): """ Construct the query body from the query and/or filter(s) (call with dict(build_body) @param query: a elastic query string (i.e. lucene syntax, e.g. 'piet AND (ja* OR klaas)') @param filter: field filter DSL query dict, defaults to build_filter(**filters) @param query_as_filter: if True, use the query as a filter (faster but not score/relevance) """ filters = list(get_filter_clauses(**filters)) if query: terms = queryparser.parse_to_terms(query) if query_as_filter: filters.append(terms.get_filter_dsl()) else: yield ('query', terms.get_dsl()) if filters: yield ('filter', combine_filters(filters))
def build_body(query=None, filters=EMPTY_RO_DICT, query_as_filter=False): """ Construct the query body from the query and/or filter(s) (call with dict(build_body) @param query: an elastic query string (i.e. lucene syntax, e.g. 'piet AND (ja* OR klaas)') @param filters: field filter DSL query dict, defaults to build_filter(**filters) @param query_as_filter: if True, use the query as a filter (faster but not score/relevance) """ filters = list(get_filter_clauses(**filters)) if query: terms = queryparser.parse_to_terms(query) if query_as_filter: filters.append(terms.get_filter_dsl()) else: yield ('query', terms.get_dsl()) if filters: yield ('filter', combine_filters(filters))
def test_parse(self): q = lambda s: str(parse_to_terms(s)) self.assertEqual(q('a'), '_all::a') self.assertEqual(q('a b'), 'OR[_all::a _all::b]') self.assertEqual(q('a OR b'), 'OR[_all::a _all::b]') self.assertEqual(q('a AND b'), 'AND[_all::a _all::b]') self.assertEqual(q('a NOT b'), 'NOT[_all::a _all::b]') self.assertEqual(q('a AND (b c)'), 'AND[_all::a OR[_all::b _all::c]]') self.assertEqual(q('(a AND b) c'), 'OR[AND[_all::a _all::b] _all::c]') # starting with NOT self.assertEqual(q('NOT a'), 'NOT[_all::a]') # quotes self.assertEqual(q('"a b"'), '_all::QUOTE[a b]') self.assertEqual(q('"a b" c'), 'OR[_all::QUOTE[a b] _all::c]') # proximity queries self.assertEqual(q('a W/10 b'), '_all::PROX/10[a b]') self.assertEqual(q('(a b) W/10 c'), '_all::PROX/10[OR[a b] c]') self.assertEqual(q('(x:a b) W/10 c'), 'x::PROX/10[OR[a b] c]') # proximity queries must have unique field and can only contain wildcards and disjunctions self.assertRaises(QueryParseError, q, 'a W/10 (b OR (c OR d))') self.assertRaises(QueryParseError, q, 'x:a W/10 y:b') self.assertRaises(QueryParseError, q, 'a W/10 (b AND c)') self.assertRaises(QueryParseError, q, 'a W/10 (b W/5 c)') # lucene notation self.assertEqual(q('"a b"~5'), '_all::PROX/5[a b]') self.assertEqual(q('x:"a b"~5'), 'x::PROX/5[a b]') self.assertEqual(q('"a (b c)"~5'), '_all::PROX/5[a OR[b c]]') # disallow AND in lucene notation self.assertRaises(QueryParseError, q, '"a (b AND c)"~5') # disallow matchall wildcards anywhere but at the beginning self.assertRaises(QueryParseError, q, '"a * b"~5') self.assertRaises(QueryParseError, q, 'a AND *') self.assertEqual(q('* NOT a'), 'NOT[_all::* _all::a]') self.assertEqual(q('*'), '_all::*')
def build_body(query=None, filters=EMPTY_RO_DICT, query_as_filter=False): """ Construct the query body from the query and/or filter(s) (call with dict(build_body) @param query: an elastic query string (i.e. lucene syntax, e.g. 'piet AND (ja* OR klaas)') @param filters: field filter DSL query dict, defaults to build_filter(**filters) @param query_as_filter: if True, use the query as a filter (faster but not score/relevance) """ query_body = {"bool": {}} filters = list(get_filter_clauses(**filters)) if query: terms = queryparser.parse_to_terms(query) if query_as_filter: filters.append(terms.get_filter_dsl()) else: query_body["bool"]["must"] = terms.get_dsl() if filters: query_body["bool"]["filter"] = filters return {"query": query_body}
def __init__(self, fields: Sequence[str], query: str, mark: str): self.query_raw = query self.query = queryparser.parse_to_terms(query) # type: Term self.fields = fields self.mark = mark