Esempio n. 1
0
    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))
Esempio n. 2
0
    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
Esempio n. 3
0
    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))
Esempio n. 4
0
    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))
Esempio n. 5
0
    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)
Esempio n. 6
0
    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_