Ejemplo n.º 1
0
 def create_index(self, keys, **kwargs):
     """
     create and index the easy way
     """
     keys, kwargs = MongoQueryOps().make_index(keys)
     result = self.collection.create_index(keys, **kwargs)
     return result
Ejemplo n.º 2
0
    def build_conditions(self):
        """
        For a given query definition return the collection.find() simple query

        Using all conditions, build the query as a dictionary suitable for
        collection.find(). This uses MongoQueryOps to transform query 
        definitions into mongo db syntax.

        :return: the query in mongo db syntax  
        """
        query = {}
        qops = MongoQueryOps()

        def addq(k, v):
            if k not in query:
                query[k] = v
            else:
                subq = []
                query.setdefault("$and", subq)
                for vv in [query.pop(k), v]:
                    if isinstance(vv, (list, tuple)):
                        subq.extend(vv)
                    else:
                        subq.append({k: vv})

        for k, v in six.iteritems(self.conditions):
            # transform query operators as '<foo>__<op>',
            # however preserve dunder '__<foo>' names ss columns
            if '__' in k and not k.startswith('__'):
                parts = k.split('__')
                k = '.'.join(parts[0:-1])
                op = parts[-1]
            else:
                op = 'eq'
            # standard logical operators
            if op == 'eq':
                addq(k, v)
            elif op.upper() in qops.UNARY:
                addq(k, getattr(qops, op)(v))
            # type queries
            elif op == 'between':
                addq("$and", [{k: qops.GTE(v[0])}, {k: qops.LTE(v[1])}])
            elif op == 'isstring':
                addq(k, qops.EQ(qops.TYPE('string')))
            elif op == 'isarray':
                addq(k, qops.EQ(qops.TYPE('array')))
            elif op == 'isdouble':
                addq(k, qops.TYPE('double'))
            elif op == 'isobject':
                addq(k, qops.TYPE('object'))
            elif op == 'isobject':
                addq(k, qops.TYPE('object'))
            elif op == 'isdate':
                addq(k, qops.TYPE('date'))
            elif op == 'isbool':
                addq(k, qops.TYPE('bool'))
            elif op == 'isnull':
                # http://stackoverflow.com/a/944733
                nan = float('nan')
                addq(k, qops.EQ(nan) if v else qops.NE(nan))
            elif op in ['islong', 'isint']:
                addq(k, qops.TYPE('long'))
            elif op == 'contains':
                addq(k, qops.REGEX('^%s.*' % v))
            elif op == 'startswith':
                addq(k, qops.REGEX('^%s.*' % v))
            elif op == 'endswith':
                addq(k, qops.REGEX('.*%s$' % v))
            elif op == 'near':
                addq(k, qops.NEAR(v))
            else:
                # op from parts[-1] was not an opperator, so assume it is
                # an attribute name and apply the eq operator
                # e.g. Q(key__subkey=value)
                addq('%s.%s' % (k, op), v)
        return query