def __query_build_by_field(self, queries): for q in queries: if ":" in q: k = q.split(":")[0].strip() v = ":".join(q.split(":")[1:]).strip() field_name, field_type, operator = self._attr_name_proc(k) if field_name: # in query if v.startswith("(") and v.endswith(")"): self._in_query_handle(field_name, v) # range query elif v.startswith("[") and v.endswith("]") and "_TO_" in v: self._range_query_handle(field_name, v, operator) # comparison query elif v.startswith(">=") or v.startswith( "<=") or v.startswith(">") or v.startswith("<"): self._comparison_query_handle(field_name, v, operator) else: self._match_query_handle(field_name, v, operator) else: raise SearchError( "argument q format invalid: {0}".format(q)) elif q: raise SearchError("argument q format invalid: {0}".format(q))
def __query_build_by_field(self, queries): query_sql, alias, operator = "", "A", "&" is_first, only_type_query_special = True, True for q in queries: _query_sql = "" if ":" in q: k = q.split(":")[0].strip() v = ":".join(q.split(":")[1:]).strip() current_app.logger.debug(v) field, field_type, operator, attr = self._attr_name_proc(k) if field == "_type": _query_sql = self._type_query_handler(v) current_app.logger.debug(_query_sql) elif field == "_id": # exclude all others ci = CI.get_by_id(v) if ci is not None: return 1, [str(v)] elif field: if attr is None: raise SearchError("{0} is not found".format(field)) # in query if v.startswith("(") and v.endswith(")"): _query_sql = self._in_query_handler(attr, v) # range query elif v.startswith("[") and v.endswith("]") and "_TO_" in v: _query_sql = self._range_query_handler(attr, v) # comparison query elif v.startswith(">=") or v.startswith("<=") or v.startswith(">") or v.startswith("<"): _query_sql = self._comparison_query_handler(attr, v) else: table_name = TableMap(attr_name=attr.name).table_name _query_sql = QUERY_CI_BY_ATTR_NAME.format( table_name, attr.id, 'LIKE "{0}"'.format(v.replace("*", "%"))) else: raise SearchError("argument q format invalid: {0}".format(q)) elif q: raise SearchError("argument q format invalid: {0}".format(q)) if is_first and _query_sql and not self.only_type_query: query_sql = "SELECT * FROM ({0}) AS {1}".format(_query_sql, alias) is_first = False alias += "A" elif self.only_type_query and only_type_query_special: is_first = False only_type_query_special = False query_sql = _query_sql elif _query_sql: query_sql = self._wrap_sql(operator, alias, _query_sql, query_sql) alias += "AA" return None, query_sql
def _sort_build(self): fields = list(filter(lambda x: x != "", (self.sort or "").split(","))) sorts = [] for field in fields: sort_type = "asc" if field.startswith("+"): field = field[1:] elif field.startswith("-"): field = field[1:] sort_type = "desc" else: field = field if field == "ci_id": sorts.append({field: {"order": sort_type}}) continue attr = AttributeCache.get(field) if not attr: raise SearchError("Sort by <{0}> does not exist".format(field)) sort_by = "{0}.keyword".format(field) \ if attr.value_type not in (ValueTypeEnum.INT, ValueTypeEnum.FLOAT) else field sorts.append({sort_by: {"order": sort_type}}) self.query.update(dict(sort=sorts))
def _attr_name_proc(self, key): operator, key = self._operator_proc(key) if key in ('ci_type', 'type', '_type'): return '_type', ValueTypeEnum.TEXT, operator, None if key in ('id', 'ci_id', '_id'): return '_id', ValueTypeEnum.TEXT, operator, None attr = AttributeCache.get(key) if attr: return attr.name, attr.value_type, operator, attr else: raise SearchError("{0} is not existed".format(key))
def _facet_build(self): aggregations = dict(aggs={}) for field in self.facet_field: attr = AttributeCache.get(field) if not attr: raise SearchError("Facet by <{0}> does not exist".format(field)) aggregations['aggs'].update({ field: { "terms": { "field": "{0}.keyword".format(field) if attr.value_type not in (ValueTypeEnum.INT, ValueTypeEnum.FLOAT) else field } } }) if aggregations['aggs']: self.query.update(aggregations)
def search(self): try: numfound, cis, facet = self._query_build_raw() except Exception as e: current_app.logger.error(str(e)) raise SearchError("unknown search error") total = len(cis) counter = dict() for ci in cis: ci_type = ci.get("ci_type") if ci_type not in counter.keys(): counter[ci_type] = 0 counter[ci_type] += 1 facet_ = dict() for k in facet: facet_[k] = [[i['key'], i['doc_count'], k] for i in facet[k]["buckets"]] return cis, counter, total, self.page, numfound, facet_