Example #1
0
def test_fuzzy():
    eq_(str(Q(fuzzy='fuzzi')), 'fuzzi~')

    try:
        Q(fuzzy='test fuzz')
    except:
        pass
    else:
        raise AssertionError("Fuzzy queries shouldn't have whitespace.")

    eq_(str(Q(fuzzy=('fuzzi', .2))), 'fuzzi~0.200')
    eq_(str(Q('field', fuzzy='fuzzi')), 'field:(fuzzi~)')
Example #2
0
def test_field_restrictions():
    q1 = Q('field', 'test query')
    assert q1.fielded

    q2 = Q('a') & q1
    assert q2.fielded

    try:
        Q('another_field', q2)
    except:
        pass
    else:
        raise AssertionError('Query allowed nested fields, which are invalid.')
Example #3
0
 def _get_filtered_nodes(self,
                         lookups,
                         label=None,
                         include_properties=None):
     # Working on indices
     idx = self.node_index.neoindex
     q = Q(r"graph", r"%s" % self.graph_id)
     if label:
         q &= Q(r"label", r"%s" % label)
     for lookup in lookups:
         l = Q()
         if lookup["lookup"] == "contains":
             l |= Q(r"%s" % lookup["property"],
                    r"*%s*" % lookup["match"],
                    wildcard=True)
         elif lookup["lookup"] == "starts":
             l |= Q(r"%s" % lookup["property"],
                    r"%s*" % lookup["match"],
                    wildcard=True)
         elif lookup["lookup"] == "ends":
             l |= Q(r"%s" % lookup["property"],
                    r"*%s" % lookup["match"],
                    wildcard=True)
         elif lookup["lookup"] == "exact":
             l |= Q(r"%s" % lookup["property"], r"%s" % lookup["match"])
     q = q & (l)
     if include_properties:
         for node in idx.query(q):
             yield (node.id, node.properties)
     else:
         for node in idx.query(q):
             yield (node.id, None)
Example #4
0
def test_lucene_query():
    Human(name='sarah', age=3).save()
    Human(name='jim', age=4).save()
    Human(name='bob', age=5).save()
    Human(name='tim', age=2).save()

    names = [p.name for p in Human.index.search(Q('age', inrange=[3, 5]))]
    assert 'sarah' in names
    assert 'jim' in names
    assert 'bob' in names
Example #5
0
    def search(self, query=None, **kwargs):
        """ Load multiple nodes via index """
        self._check_params(kwargs)
        if not query:
            query = reduce(lambda x, y: x & y,
                           [Q(k, v) for k, v in kwargs.iteritems()])

        return [
            self.node_class.inflate(n)
            for n in self.__index__.query(str(query))
        ]
Example #6
0
    def search(self, query=None, **kwargs):
        """Search nodes using an via index"""
        if not query:
            if not kwargs:
                msg = "No arguments provided.\nUsage: {0}.index.search(key=val)"
                msg += " or (lucene query): {0}.index.search('key:val').\n"
                msg += "To retrieve all nodes use the category node: {0}.category().instance.all()"
                raise ValueError(msg.format(self.node_class.__name__))
            self._check_params(kwargs)
            query = functools.reduce(lambda x, y: x & y,
                                     [Q(k, v) for k, v in kwargs.items()])

        return [self.node_class.inflate(n) for n in self._execute(str(query))]
Example #7
0
    def search(self, query=None, **kwargs):
        """Search nodes using an via index, if searching just for one
        properties, attemps to find if the property is on his own index"""
        index = self.__index__
        if not query:
            if not kwargs:
                msg = "No arguments provided.\nUsage: {0}.index.search(key=val)"
                msg += " or (lucene query): {0}.index.search('key:val').\n"
                msg += "To retrieve all nodes use the category node: {0}.category().instance.all()"
                raise ValueError(msg.format(self.node_class.__name__))
            self._check_params(kwargs)
            if len(kwargs.keys()) == 1:
                index = self._get_index(kwargs.keys()[0])
                is_fulltext = self._get_index_type(kwargs.keys()[0]) == \
                              'fulltext'
                if is_fulltext:
                    qargs = {'wildcard': True}
                else:
                    qargs = None
            if qargs:
                query = functools.reduce(
                    lambda x, y: x & y,
                    [Q(k, v, **qargs) for k, v in kwargs.items()])
            else:
                query = functools.reduce(
                    lambda x, y: x & y, [Q(
                        k,
                        v,
                    ) for k, v in kwargs.items()])
        elif not isinstance(query, Q):
            if len(query.split(':')) == 2:
                index = self._get_index(query.split(':')[0])

        return [
            self.node_class.inflate(n)
            for n in self._execute(index, str(query))
        ]
Example #8
0
def test_hashing():
    q1 = Q('a') & Q('b') | Q('c')
    q2 = Q('a') & Q('b') | Q('c')
    q3 = q1 | Q('d')

    assert q1 == q2, "Queries aren't being properly evaluated for equality."
    assert q2 != q3, "Queries aren't being properly evaluated for inequality."

    d = {}
    try:
        d[q1] = 1
        d[q2] = 2
    except:
        raise AssertionError('There was an error using queries as dict keys.')
    assert d[q2] == 2, 'Got the wrong value back from the query dict!'

    q4 = Q('field', inrange=(1, 2))
    q5 = Q('field', inrange=(1, 3))
    assert q4 != q5
    assert hash(q4) != hash(q5)
Example #9
0
 def test_query_index(self):
     n1 = self.gdb.nodes.create(name="John Doe", place="Texas")
     n2 = self.gdb.nodes.create(name="Michael Donald", place="Tijuana")
     index = self.gdb.nodes.indexes.create(name="do", type="fulltext")
     index["surnames"]["doe"] = n1
     index["surnames"]["donald"] = n2
     index['place']['Texas'] = n1
     index['place']['Tijuana'] = n2
     results = index.query("surnames", "do*")
     self.assertTrue(n1 in results and n2 in results)
     results = index.query("surnames:do*")
     self.assertTrue(n1 in results and n2 in results)
     results = index.query('surnames', Q('do*', wildcard=True))
     self.assertTrue(n1 in results and n2 in results)
     results = index.query(Q('surnames', 'do*', wildcard=True))
     self.assertTrue(n1 in results and n2 in results)
     results = index.query(
         Q('surnames', 'do*', wildcard=True) & Q('place', 'Tijuana'))
     self.assertTrue(n1 not in results and n2 in results)
     results = index.query(-Q('surnames', 'donald') | +Q('place', 'Texas'))
     self.assertTrue(n2 not in results and n1 in results)
Example #10
0
def q_from_condition(condition):
    """
    Build a Lucene query from a filtering condition.
    """
    q = None
    field = condition.field
    attname = field.attname
    def escape_wilds(s):
        return str(s).replace('*','\*').replace('?','\?')
    if condition.operator is OPERATORS.EXACT:
        q = Q(attname, field.to_neo_index(condition.value))
    elif condition.operator is OPERATORS.STARTSWITH:
        q = Q(attname, '%s*' % escape_wilds(condition.value), wildcard=True)
    elif condition.operator is OPERATORS.CONTAINS:
        q = Q(attname, '*%s*' % escape_wilds(condition.value), wildcard=True)
    elif condition.operator is OPERATORS.MEMBER:
        q = Q(attname, field.member_to_neo_index(condition.value))
    elif condition.operator is OPERATORS.IN:
        q = reduce(or_, (Q(attname, field.to_neo_index(v)) for v in condition.value))
    elif condition.operator is OPERATORS.MEMBER_IN:
        q = reduce(or_, (Q(attname, field.member_to_neo_index(v)) for v in condition.value))
    #FIXME OBOE with field.MAX + exrange, not sure it's easy to fix though...
    elif condition.operator in (OPERATORS.GT, OPERATORS.GTE, OPERATORS.LT,
                                OPERATORS.LTE, OPERATORS.RANGE): 
        if not field.indexed_range:
            raise exceptions.FieldError(
                'The {0} property is not configured for range '
                'indexing.'.format(field.attname))
        fieldtype = field._property_type()
        if condition.operator in (OPERATORS.GT, OPERATORS.GTE):
            if not hasattr(field, 'MAX'):
                raise exceptions.FieldError(
                    'The {0} property is not configured for gt/gte '
                    'queries.'.format(field.attname))
            if condition.operator is OPERATORS.GT:
                q = Q(attname, exrange=(field.to_neo_index(condition.value),
                                        field.to_neo_index(fieldtype.MAX)))
            else:
                q = Q(attname, inrange=(field.to_neo_index(condition.value),
                                        field.to_neo_index(fieldtype.MAX)))
        elif condition.operator in (OPERATORS.LT, OPERATORS.LTE):
            if not hasattr(fieldtype, 'MIN'):
                raise exceptions.FieldError(
                    'The {0} property is not configured for lt/lte '
                    'queries.'.format(field.attname))
            if condition.operator is OPERATORS.LT:
                q = Q(attname, exrange=(field.to_neo_index(fieldtype.MIN),
                                        field.to_neo_index(condition.value)))
            else:
                q = Q(attname, inrange=(field.to_neo_index(fieldtype.MIN),
                                        field.to_neo_index(condition.value)))
        elif condition.operator is OPERATORS.RANGE:
            if len(condition.value) != 2:
                raise exceptions.ValidationError('Range queries need upper and'
                                                ' lower bounds.')
            q = Q(condition.field.attname,
                inrange=[condition.field.to_neo_index(v)
                         for v in condition.value])
    else:
        return None
    if condition.negate:
        q = ~q
    return q
Example #11
0
def test_general():
    a = 'a'
    b = 'b'
    c = 'c'
    d = 'd d'
    e = 'e'
    f = 'f'
    g = 1
    h = 5
    q1 = Q(a) | Q(b)
    assert str(q1) == '(' + a + ' OR ' + b + ')', str(q1)
    q2 = Q(c) & q1
    assert str(q2) == '(' + c + ' AND (' + a + ' OR ' + b + '))'
    q3 = +Q(a) + Q(b) | Q(f, Q(c) & ~Q(Q(d) | Q(e)))
    assert str(
        q3
    ) == '+' + a + ' +' + b + ' ' + f + ':((' + c + ' AND NOT ' + '("' + d + '" OR ' + e + ')))'
    q4 = Q(a, b) | Q(c, Q(d) & Q(e)) | Q(f, +Q(inrange=(g, h)) | Q(h))
    assert str(
        q4
    ) == a + ':(' + b + ') ' + c + ':(("' + d + '" AND ' + e + ')) ' + f + ':(+[' + str(
        g) + ' TO ' + str(h) + '] ' + str(h) + ')'
    try:
        q5 = Q(a, Q(b, Q(c, d) & Q(e)) | Q(f))
    except:
        pass
    else:
        raise AssertionError("Shouldn't allow nested fields.")
Example #12
0
def test_simple_phrase():
    query_string = str(Q('abc 123'))
    assert query_string == '"abc 123"', query_string
Example #13
0
def test_simple_term():
    query_string = str(Q('a'))
    assert query_string == 'a', query_string
Example #14
0
def test_wildcard():
    eq_(str(Q('lol*', wildcard=True)), 'lol*')
    eq_(str(Q('field_with_*', 'some query')), 'field_with_*:("some query")')
    eq_(str(Q('field_with_*', 'some*query', wildcard=True)),
        'field_with_*:(some*query)')