def _build_sub_query(self, search_node): term_list = [] for child in search_node.children: if isinstance(child, SearchNode): term_list.append(self._build_sub_query(child)) else: value = child[1] if not hasattr(value, 'input_type_name'): value = PythonData(value) term_list.append(value.prepare(self)) return (' ').join(map(str, term_list))
def build_query_fragment(self, field, filter_type, value): from haystack import connections query_frag = '' is_datetime = False if not hasattr(value, 'input_type_name'): # Handle when we've got a ``ValuesListQuerySet``... if hasattr(value, 'values_list'): value = list(value) if hasattr(value, 'strftime'): is_datetime = True if isinstance(value, six.string_types) and value != ' ': # It's not an ``InputType``. Assume ``Clean``. value = Clean(value) else: value = PythonData(value) # Prepare the query using the InputType. prepared_value = value.prepare(self) if not isinstance(prepared_value, (set, list, tuple)): # Then convert whatever we get back to what pysolr wants if needed. prepared_value = self.backend._from_python(prepared_value) # 'content' is a special reserved word, much like 'pk' in # Django's ORM layer. It indicates 'no special field'. if field == 'content': index_fieldname = '' else: index_fieldname = u'%s:' % connections[self._using].get_unified_index().get_index_fieldname(field) filter_types = { 'content': '%s', 'contains': '*%s*', 'endswith': "*%s", 'startswith': "%s*", 'exact': '%s', 'gt': "{%s to}", 'gte': "[%s to]", 'lt': "{to %s}", 'lte': "[to %s]", 'fuzzy': u'%s~', } if value.post_process is False: query_frag = prepared_value else: if filter_type in ['content', 'contains', 'startswith', 'endswith', 'fuzzy']: if value.input_type_name == 'exact': query_frag = prepared_value else: # Iterate over terms & incorportate the converted form of each into the query. terms = [] if isinstance(prepared_value, six.string_types): possible_values = prepared_value.split(' ') else: if is_datetime is True: prepared_value = self._convert_datetime(prepared_value) possible_values = [prepared_value] for possible_value in possible_values: terms.append(filter_types[filter_type] % self.backend._from_python(possible_value)) if len(terms) == 1: query_frag = terms[0] else: query_frag = u"(%s)" % " AND ".join(terms) elif filter_type == 'in': in_options = [] for possible_value in prepared_value: is_datetime = False if hasattr(possible_value, 'strftime'): is_datetime = True pv = self.backend._from_python(possible_value) if is_datetime is True: pv = self._convert_datetime(pv) if isinstance(pv, six.string_types) and not is_datetime: in_options.append('"%s"' % pv) else: in_options.append('%s' % pv) query_frag = "(%s)" % " OR ".join(in_options) elif filter_type == 'range': start = self.backend._from_python(prepared_value[0]) end = self.backend._from_python(prepared_value[1]) if hasattr(prepared_value[0], 'strftime'): start = self._convert_datetime(start) if hasattr(prepared_value[1], 'strftime'): end = self._convert_datetime(end) query_frag = u"[%s to %s]" % (start, end) elif filter_type == 'exact': if value.input_type_name == 'exact': query_frag = prepared_value else: prepared_value = Exact(prepared_value).prepare(self) query_frag = filter_types[filter_type] % prepared_value else: if is_datetime is True: prepared_value = self._convert_datetime(prepared_value) query_frag = filter_types[filter_type] % prepared_value if len(query_frag) and not isinstance(value, Raw): if not query_frag.startswith('(') and not query_frag.endswith(')'): query_frag = "(%s)" % query_frag return u"%s%s" % (index_fieldname, query_frag)
def build_query_fragment(self, field, filter_type, value): from haystack import connections query_frag = "" if not hasattr(value, "input_type_name"): # Handle when we've got a ``ValuesListQuerySet``... if hasattr(value, "values_list"): value = list(value) if isinstance(value, six.string_types): # It's not an ``InputType``. Assume ``Clean``. value = Clean(value) else: value = PythonData(value) # Prepare the query using the InputType. prepared_value = value.prepare(self) if not isinstance(prepared_value, (set, list, tuple)): # Then convert whatever we get back to what pysolr wants if needed. prepared_value = self.backend._from_python(prepared_value) # 'content' is a special reserved word, much like 'pk' in # Django's ORM layer. It indicates 'no special field'. if field == "content": index_fieldname = "" else: index_fieldname = "%s:" % connections[ self._using].get_unified_index().get_index_fieldname(field) filter_types = { "content": "%s", "contains": "*%s*", "endswith": "*%s", "startswith": "%s*", "exact": "%s", "gt": "{%s TO *}", "gte": "[%s TO *]", "lt": "{* TO %s}", "lte": "[* TO %s]", "fuzzy": "%s~", } if value.post_process is False: query_frag = prepared_value else: if filter_type in [ "content", "contains", "startswith", "endswith", "fuzzy", ]: if value.input_type_name == "exact": query_frag = prepared_value else: # Iterate over terms & incorportate the converted form of each into the query. terms = [] if isinstance(prepared_value, six.string_types): for possible_value in prepared_value.split(" "): terms.append( filter_types[filter_type] % self.backend._from_python(possible_value)) else: terms.append(filter_types[filter_type] % self.backend._from_python(prepared_value)) if len(terms) == 1: query_frag = terms[0] else: query_frag = "(%s)" % " AND ".join(terms) elif filter_type == "in": in_options = [] if not prepared_value: query_frag = "(!*:*)" else: for possible_value in prepared_value: in_options.append( '"%s"' % self.backend._from_python(possible_value)) query_frag = "(%s)" % " OR ".join(in_options) elif filter_type == "range": start = self.backend._from_python(prepared_value[0]) end = self.backend._from_python(prepared_value[1]) query_frag = '["%s" TO "%s"]' % (start, end) elif filter_type == "exact": if value.input_type_name == "exact": query_frag = prepared_value else: prepared_value = Exact(prepared_value).prepare(self) query_frag = filter_types[filter_type] % prepared_value else: if value.input_type_name != "exact": prepared_value = Exact(prepared_value).prepare(self) query_frag = filter_types[filter_type] % prepared_value if len(query_frag) and not isinstance(value, Raw): if not query_frag.startswith("(") and not query_frag.endswith(")"): query_frag = "(%s)" % query_frag return "%s%s" % (index_fieldname, query_frag)
def build_query_fragment(self, field, filter_type, value): from haystack import connections query_frag = "" is_datetime = False if not hasattr(value, "input_type_name"): # Handle when we've got a ``ValuesListQuerySet``... if hasattr(value, "values_list"): value = list(value) if hasattr(value, "strftime"): is_datetime = True if isinstance(value, str) and value != " ": # It's not an ``InputType``. Assume ``Clean``. value = Clean(value) else: value = PythonData(value) # Prepare the query using the InputType. prepared_value = value.prepare(self) if not isinstance(prepared_value, (set, list, tuple)): # Then convert whatever we get back to what pysolr wants if needed. prepared_value = self.backend._from_python(prepared_value) # 'content' is a special reserved word, much like 'pk' in # Django's ORM layer. It indicates 'no special field'. if field == "content": index_fieldname = "" else: index_fieldname = "%s:" % connections[ self._using].get_unified_index().get_index_fieldname(field) filter_types = { "content": "%s", "contains": "*%s*", "endswith": "*%s", "startswith": "%s*", "exact": "%s", "gt": "{%s to}", "gte": "[%s to]", "lt": "{to %s}", "lte": "[to %s]", "fuzzy": "%s~{}/%d".format(FUZZY_WHOOSH_MAX_EDITS), } if value.post_process is False: query_frag = prepared_value else: if filter_type in [ "content", "contains", "startswith", "endswith", "fuzzy", ]: if value.input_type_name == "exact": query_frag = prepared_value else: # Iterate over terms & incorportate the converted form of each into the query. terms = [] if isinstance(prepared_value, str): possible_values = prepared_value.split(" ") else: if is_datetime is True: prepared_value = self._convert_datetime( prepared_value) possible_values = [prepared_value] for possible_value in possible_values: possible_value_str = self.backend._from_python( possible_value) if filter_type == "fuzzy": terms.append(filter_types[filter_type] % (possible_value_str, min(FUZZY_WHOOSH_MIN_PREFIX, len(possible_value_str)))) else: terms.append(filter_types[filter_type] % possible_value_str) if len(terms) == 1: query_frag = terms[0] else: query_frag = "(%s)" % " AND ".join(terms) elif filter_type == "in": in_options = [] for possible_value in prepared_value: is_datetime = False if hasattr(possible_value, "strftime"): is_datetime = True pv = self.backend._from_python(possible_value) if is_datetime is True: pv = self._convert_datetime(pv) if isinstance(pv, str) and not is_datetime: in_options.append('"%s"' % pv) else: in_options.append("%s" % pv) query_frag = "(%s)" % " OR ".join(in_options) elif filter_type == "range": start = self.backend._from_python(prepared_value[0]) end = self.backend._from_python(prepared_value[1]) if hasattr(prepared_value[0], "strftime"): start = self._convert_datetime(start) if hasattr(prepared_value[1], "strftime"): end = self._convert_datetime(end) query_frag = "[%s to %s]" % (start, end) elif filter_type == "exact": if value.input_type_name == "exact": query_frag = prepared_value else: prepared_value = Exact(prepared_value).prepare(self) query_frag = filter_types[filter_type] % prepared_value else: if is_datetime is True: prepared_value = self._convert_datetime(prepared_value) query_frag = filter_types[filter_type] % prepared_value if len(query_frag) and not isinstance(value, Raw): if not query_frag.startswith("(") and not query_frag.endswith(")"): query_frag = "(%s)" % query_frag return "%s%s" % (index_fieldname, query_frag)
def build_query_fragment(self, field, filter_type, value): from haystack import connections query_frag = '' if not hasattr(value, 'input_type_name'): # Handle when we've got a ``ValuesListQuerySet``... if hasattr(value, 'values_list'): value = list(value) if isinstance(value, six.string_types): # It's not an ``InputType``. Assume ``Clean``. value = Clean(value) else: value = PythonData(value) # Prepare the query using the InputType. prepared_value = value.prepare(self) if not isinstance(prepared_value, (set, list, tuple)): # Then convert whatever we get back to what elasticsearch wants if needed. prepared_value = self.backend._from_python(prepared_value, for_query=True) # 'content' is a special reserved word, much like 'pk' in # Django's ORM layer. It indicates 'no special field'. if field == 'content': index_fieldname = '' else: index_fieldname = u'%s:' % connections[self._using].get_unified_index().get_index_fieldname(field) filter_types = { 'contains': u'%s', 'startswith': u'%s*', 'exact': u'%s', 'gt': u'{%s TO *}', 'gte': u'[%s TO *]', 'lt': u'{* TO %s}', 'lte': u'[* TO %s]', } if value.post_process is False: query_frag = prepared_value else: if filter_type in ['contains', 'startswith']: if value.input_type_name == 'exact': query_frag = prepared_value else: # Iterate over terms & incorporate the converted form of each into the query. terms = [] if isinstance(prepared_value, six.string_types): for possible_value in prepared_value.split(' '): terms.append(filter_types[filter_type] % self.backend._from_python(possible_value, for_query=True)) else: terms.append(filter_types[filter_type] % self.backend._from_python(prepared_value, for_query=True)) if len(terms) == 1: query_frag = terms[0] else: query_frag = u"(%s)" % " AND ".join(terms) elif filter_type == 'in': in_options = [] if len(prepared_value) >= 500: from elation.util.exception import log_warning log_warning(msg="Found %s values in an ES IN clause" % (len(prepared_value),)) for possible_value in prepared_value: in_options.append(u'"%s"' % self.backend._from_python(possible_value, for_query=True)) query_frag = u"(%s)" % " OR ".join(in_options) elif filter_type == 'range': start = self.backend._from_python(prepared_value[0], for_query=True) end = self.backend._from_python(prepared_value[1], for_query=True) query_frag = u'["%s" TO "%s"]' % (start, end) elif filter_type == 'exact': if value.input_type_name == 'exact': query_frag = prepared_value else: prepared_value = Exact(prepared_value).prepare(self) query_frag = filter_types[filter_type] % prepared_value else: if value.input_type_name != 'exact': prepared_value = Exact(prepared_value).prepare(self) query_frag = filter_types[filter_type] % prepared_value if len(query_frag) and not isinstance(value, Raw): if not query_frag.startswith('(') and not query_frag.endswith(')'): query_frag = "(%s)" % query_frag return u"%s%s" % (index_fieldname, query_frag)
def build_query_fragment(self, field, filter_type, value): from haystack import connections query_frag = '' if not hasattr(value, 'input_type_name'): # Handle when we've got a ``ValuesListQuerySet``... if hasattr(value, 'values_list'): value = list(value) if filter_type in ["regex", "iregex"]: value = RegExp(value) elif isinstance(value, six.string_types): # It's not an ``InputType``. Assume ``Clean``. value = Clean(value) else: value = PythonData(value) # Prepare the query using the InputType. prepared_value = value.prepare(self) if not isinstance(prepared_value, (set, list, tuple)): # Then convert whatever we get back to what pysolr wants if needed. prepared_value = self.backend.conn._from_python(prepared_value) # 'content' is a special reserved word, much like 'pk' in # Django's ORM layer. It indicates 'no special field'. if field == 'content': index_fieldname = '' else: index_fieldname = \ u'%s:' % connections[self._using].\ get_unified_index().get_index_fieldname(field) filter_types = { 'content': u'%s', 'contains': u'*%s*', 'endswith': u'*%s', 'startswith': u'%s*', 'exact': u'%s', 'gt': u'{%s TO *}', 'gte': u'[%s TO *]', 'lt': u'{* TO %s}', 'lte': u'[* TO %s]', 'fuzzy': u'%s~', 'regex': u'/%s/', 'iregex': u'/%s/', } if value.post_process is False: query_frag = prepared_value else: if filter_type in \ ['content', 'contains', 'startswith', 'endswith', 'fuzzy', 'regex', 'iregex']: if value.input_type_name == 'exact': query_frag = prepared_value else: # Iterate over terms & incorportate the converted # form of each into the query. terms = [] for possible_value in prepared_value.split(' '): terms.append( filter_types[filter_type] % (self.backend.conn._from_python(possible_value) if filter_type not in ['regex', 'iregex'] else possible_value)) if len(terms) == 1: query_frag = terms[0] else: query_frag = u"(%s)" % " AND ".join(terms) elif filter_type == 'in': in_options = [] if not prepared_value: query_frag = u'(!*:*)' else: for possible_value in prepared_value: in_options.append( u'"%s"' % self.backend.conn._from_python(possible_value)) query_frag = u"(%s)" % " OR ".join(in_options) elif filter_type == 'range': start = self.backend.conn._from_python(prepared_value[0]) end = self.backend.conn._from_python(prepared_value[1]) query_frag = u'["%s" TO "%s"]' % (start, end) elif filter_type == 'exact': if value.input_type_name == 'exact': query_frag = prepared_value else: prepared_value = Exact(prepared_value).prepare(self) query_frag = filter_types[filter_type] % prepared_value else: if value.input_type_name != 'exact': prepared_value = Exact(prepared_value).prepare(self) query_frag = filter_types[filter_type] % prepared_value if len(query_frag) and not isinstance(value, Raw) and \ filter_type not in ['regex', 'iregex']: if not query_frag.startswith('(') and not query_frag.endswith(')'): query_frag = "(%s)" % query_frag return u"%s%s" % (index_fieldname, query_frag)