From 14a1b00f498887864aab18e42a102bf39bbcf9ab Mon Sep 17 00:00:00 2001 From: Gerben Date: Wed, 6 Aug 2014 16:07:05 -0700 Subject: [PATCH 1/2] Search using a match query rather than term filter --- annotator/annotation.py | 20 +++++++++++--------- annotator/elasticsearch.py | 14 +++++++------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/annotator/annotation.py b/annotator/annotation.py index 31e09af..33f6da7 100644 --- a/annotator/annotation.py +++ b/annotator/annotation.py @@ -113,18 +113,20 @@ def _build_query(cls, query=None, offset=None, limit=None, # attempt to expand query to include uris for other representations # using information we may have on hand about the Document if 'uri' in query: - term_filter = q['query']['filtered']['filter'] + clauses = q['query']['bool'] doc = document.Document.get_by_uri(query['uri']) if doc: - new_terms = [] - for term in term_filter['and']: - if 'uri' in term['term']: - term = {'or': []} + for clause in clauses['must']: + # Rewrite the 'uri' clause to match any of the document URIs + if 'match' in clause and 'uri' in clause['match']: + uri_matchers = [] for uri in doc.uris(): - term['or'].append({'term': {'uri': uri}}) - new_terms.append(term) - - term_filter['and'] = new_terms + uri_matchers.append({'match': {'uri': uri}}) + del clause['match'] + clause['bool'] = { + 'should': uri_matchers, + 'minimum_should_match': 1 + } if es.authorization_enabled: # Apply a filter to the results. diff --git a/annotator/elasticsearch.py b/annotator/elasticsearch.py index b284fdd..c16b35f 100644 --- a/annotator/elasticsearch.py +++ b/annotator/elasticsearch.py @@ -232,15 +232,15 @@ def _csv_split(s, delimiter=','): def _build_query(query, offset, limit): # Base query is a filtered match_all - q = {'match_all': {}} - - if query: - f = {'and': []} - q = {'filtered': {'query': q, 'filter': f}} + match_clauses = [ + # We start with a single match_all because Elasticsearch considers an + # empty conjunction to be false.. + {'match_all': {}} + ] # Add a term query for each keyword for k, v in iteritems(query): - q['filtered']['filter']['and'].append({'term': {k: v}}) + match_clauses.append({'match': {k: v}}) return { 'sort': [{'updated': { @@ -255,7 +255,7 @@ def _build_query(query, offset, limit): }}], 'from': max(0, offset), 'size': min(RESULTS_MAX_SIZE, max(0, limit)), - 'query': q + 'query': {'bool': {'must': match_clauses}} } From 63735a2f7b606722e1a7411dd9049df40f23ea53 Mon Sep 17 00:00:00 2001 From: Gerben Date: Wed, 24 Sep 2014 13:05:34 +0300 Subject: [PATCH 2/2] Only add match_all to query when needed --- annotator/elasticsearch.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/annotator/elasticsearch.py b/annotator/elasticsearch.py index c16b35f..d6b8a5c 100644 --- a/annotator/elasticsearch.py +++ b/annotator/elasticsearch.py @@ -231,16 +231,12 @@ def _csv_split(s, delimiter=','): def _build_query(query, offset, limit): - # Base query is a filtered match_all - match_clauses = [ - # We start with a single match_all because Elasticsearch considers an - # empty conjunction to be false.. - {'match_all': {}} - ] - - # Add a term query for each keyword - for k, v in iteritems(query): - match_clauses.append({'match': {k: v}}) + # Create a match query for each keyword + match_clauses = [{'match': {k: v}} for k, v in iteritems(query)] + + if len(match_clauses) == 0: + # Elasticsearch considers an empty conjunction to be false.. + match_clauses.append({'match_all': {}}) return { 'sort': [{'updated': {