예제 #1
0
 def __init__(self, compiler, fields):
     super(DBQuery, self).__init__(compiler, fields)
     self._connection = self.connection.db_connection
     self._ordering = []
     self.db_query = ConstantScoreQuery()
예제 #2
0
 def __init__(self, compiler, fields):
     super(DBQuery, self).__init__(compiler, fields)
     self._connection = self.connection.db_connection
     self._ordering = []
     self.db_query = ConstantScoreQuery()
예제 #3
0
class DBQuery(NonrelQuery):
    # ----------------------------------------------
    # Public API
    # ----------------------------------------------
    def __init__(self, compiler, fields):
        super(DBQuery, self).__init__(compiler, fields)
        self._connection = self.connection.db_connection
        self._ordering = []
        self.db_query = ConstantScoreQuery()

    # This is needed for debugging
    def __repr__(self):
        return '<DBQuery: %r ORDER %r>' % (self.db_query, self._ordering)

    @safe_call
    def fetch(self, low_mark, high_mark):
        results = self._get_results()

        if low_mark > 0:
            results = results[low_mark:]
        if high_mark is not None:
            results = results[low_mark:high_mark - low_mark]

        for hit in results:
            entity = hit.get_data()
            entity['id'] = hit.meta.id
            yield entity

    @safe_call
    def count(self, limit=None):
        query = self.db_query
        if self.db_query.is_empty():
            query = MatchAllQuery()

        res = self._connection.count(query, doc_types=self.query.model._meta.db_table)
        return res["count"]

    @safe_call
    def delete(self):
        self._collection.remove(self.db_query)

    @safe_call
    def order_by(self, ordering):
        for order in ordering:
            if order.startswith('-'):
                order, direction = order[1:], {"reverse" : True}
            else:
                direction = 'desc'
            self._ordering.append({order: direction})

    # This function is used by the default add_filters() implementation
    @safe_call
    def add_filter(self, column, lookup_type, negated, db_type, value):
        if column == self.query.get_meta().pk.column:
            column = '_id'
        # Emulated/converted lookups

        if negated and lookup_type in NEGATED_OPERATORS_MAP:
            op = NEGATED_OPERATORS_MAP[lookup_type]
            negated = False
        else:
            op = OPERATORS_MAP[lookup_type]
        value = op(self.convert_value_for_db(db_type, value))

        queryf = self._get_query_type(column, lookup_type, db_type, value)

        if negated:
            self.db_query.add([NotFilter(queryf)])
        else:
            self.db_query.add([queryf])

    def _get_query_type(self, column, lookup_type, db_type, value):
        if db_type == "unicode":
            if (lookup_type == "exact" or lookup_type == "iexact"):
                q = TermQuery(column, value)
                return q
            if (lookup_type == "startswith" or lookup_type == "istartswith"):
                return RegexTermFilter(column, value)
            if (lookup_type == "endswith" or lookup_type == "iendswith"):
                return RegexTermFilter(column, value)
            if (lookup_type == "contains" or lookup_type == "icontains"):
                return RegexTermFilter(column, value)
            if (lookup_type == "regex" or lookup_type == "iregex"):
                return RegexTermFilter(column, value)

        if db_type == "datetime" or db_type == "date":
            if (lookup_type == "exact" or lookup_type == "iexact"):
                return TermFilter(column, value)

        #TermFilter, TermsFilter
        if lookup_type in ["gt", "gte", "lt", "lte", "range", "year"]:
            value['field'] = column
            return RangeQuery(ESRange(**value))
        if lookup_type == "in":
#            terms = [TermQuery(column, val) for val in value]
#            if len(terms) == 1:
#                return terms[0]
#            return BoolQuery(should=terms)
            return TermsFilter(field=column, values=value)
        raise NotImplemented

    def _get_results(self):
        """
        @returns: elasticsearch iterator over results
        defined by self.query
        """
        query = self.db_query
        if self.db_query.is_empty():
            query = MatchAllQuery()
        if self._ordering:
            query.sort = self._ordering
        #print "query", self.query.tables, query
        return self._connection.search(query, indices=[self.connection.db_name], doc_types=self.query.model._meta.db_table)
예제 #4
0
class DBQuery(NonrelQuery):
    # ----------------------------------------------
    # Public API
    # ----------------------------------------------
    def __init__(self, compiler, fields):
        super(DBQuery, self).__init__(compiler, fields)
        self._connection = self.connection.db_connection
        self._ordering = []
        self.db_query = ConstantScoreQuery()

    # This is needed for debugging
    def __repr__(self):
        return '<DBQuery: %r ORDER %r>' % (self.db_query, self._ordering)

    @safe_call
    def fetch(self, low_mark, high_mark):
        results = self._get_results()

        if low_mark > 0:
            results = results[low_mark:]
        if high_mark is not None:
            results = results[low_mark:high_mark - low_mark]

        for hit in results:
            entity = hit.get_data()
            entity['id'] = hit.meta.id
            yield entity

    @safe_call
    def count(self, limit=None):
        query = self.db_query
        if self.db_query.is_empty():
            query = MatchAllQuery()

        res = self._connection.count(query,
                                     doc_types=self.query.model._meta.db_table)
        return res["count"]

    @safe_call
    def delete(self):
        self._collection.remove(self.db_query)

    @safe_call
    def order_by(self, ordering):
        for order in ordering:
            if order.startswith('-'):
                order, direction = order[1:], {"reverse": True}
            else:
                direction = 'desc'
            self._ordering.append({order: direction})

    # This function is used by the default add_filters() implementation
    @safe_call
    def add_filter(self, column, lookup_type, negated, db_type, value):
        if column == self.query.get_meta().pk.column:
            column = '_id'
        # Emulated/converted lookups

        if negated and lookup_type in NEGATED_OPERATORS_MAP:
            op = NEGATED_OPERATORS_MAP[lookup_type]
            negated = False
        else:
            op = OPERATORS_MAP[lookup_type]
        value = op(self.convert_value_for_db(db_type, value))

        queryf = self._get_query_type(column, lookup_type, db_type, value)

        if negated:
            self.db_query.add([NotFilter(queryf)])
        else:
            self.db_query.add([queryf])

    def _get_query_type(self, column, lookup_type, db_type, value):
        if db_type == "unicode":
            if (lookup_type == "exact" or lookup_type == "iexact"):
                q = TermQuery(column, value)
                return q
            if (lookup_type == "startswith" or lookup_type == "istartswith"):
                return RegexTermFilter(column, value)
            if (lookup_type == "endswith" or lookup_type == "iendswith"):
                return RegexTermFilter(column, value)
            if (lookup_type == "contains" or lookup_type == "icontains"):
                return RegexTermFilter(column, value)
            if (lookup_type == "regex" or lookup_type == "iregex"):
                return RegexTermFilter(column, value)

        if db_type == "datetime" or db_type == "date":
            if (lookup_type == "exact" or lookup_type == "iexact"):
                return TermFilter(column, value)

        #TermFilter, TermsFilter
        if lookup_type in ["gt", "gte", "lt", "lte", "range", "year"]:
            value['field'] = column
            return RangeQuery(ESRange(**value))
        if lookup_type == "in":
            #            terms = [TermQuery(column, val) for val in value]
            #            if len(terms) == 1:
            #                return terms[0]
            #            return BoolQuery(should=terms)
            return TermsFilter(field=column, values=value)
        raise NotImplemented

    def _get_results(self):
        """
        @returns: elasticsearch iterator over results
        defined by self.query
        """
        query = self.db_query
        if self.db_query.is_empty():
            query = MatchAllQuery()
        if self._ordering:
            query.sort = self._ordering
        #print "query", self.query.tables, query
        return self._connection.search(
            query,
            indices=[self.connection.db_name],
            doc_types=self.query.model._meta.db_table)