示例#1
0
    def test_q_basic_add(self):
        """Adding one Q to another Q combines them."""
        q = Q(foo__text='abc') + Q(bar__text='def')

        eq_(sorted(q.should_q), [])
        eq_(sorted(q.must_q), [('bar__text', 'def'), ('foo__text', 'abc')])
        eq_(sorted(q.must_not_q), [])
示例#2
0
    def test_q_fuzzy(self):
        # Mispelled word gets no results with text query.
        eq_(len(self.get_s().query(foo__text='tran')), 0)

        eq_(len(self.get_s().query(Q(foo__text='tran'))), 0)

        # Mispelled word gets one result with fuzzy query.
        eq_(len(self.get_s().query(foo__fuzzy='tran')), 1)

        eq_(len(self.get_s().query(Q(foo__fuzzy='tran'))), 1)
示例#3
0
    def test_q_range(self):
        eq_(len(self.get_s().query(height__gt=10)), 1)
        eq_(len(self.get_s().query(height__gte=7)), 3)
        eq_(len(self.get_s().query(height__lt=10)), 4)
        eq_(len(self.get_s().query(height__lte=7)), 4)

        eq_(len(self.get_s().query(Q(height__gt=10))), 1)
        eq_(len(self.get_s().query(Q(height__gte=7))), 3)
        eq_(len(self.get_s().query(Q(height__lt=10))), 4)
        eq_(len(self.get_s().query(Q(height__lte=7))), 4)
示例#4
0
    def test_q_query_string(self):
        eq_(len(self.get_s().query(foo__query_string='car AND train')), 1)
        eq_(len(self.get_s().query(foo__query_string='car OR duck')), 3)

        eq_(len(self.get_s().query(Q(foo__query_string='car AND train'))), 1)
        eq_(len(self.get_s().query(Q(foo__query_string='car OR duck'))), 3)

        # You can query against different fields with the query_string.
        eq_(len(self.get_s().query(foo__query_string='tag:boat OR car')), 3)

        eq_(len(self.get_s().query(Q(foo__query_string='tag:boat OR car'))), 3)
示例#5
0
    def test_q_range_action(self):
        eq_(len(self.get_s().query(height__range=(10, 20))), 1)
        eq_(len(self.get_s().query(height__range=(0, 7))), 4)
        eq_(len(self.get_s().query(height__range=(5, 7))), 3)

        eq_(len(self.get_s().query(Q(height__range=(10, 20)))), 1)
        eq_(len(self.get_s().query(Q(height__range=(0, 7)))), 4)
        eq_(len(self.get_s().query(Q(height__range=(5, 7)))), 3)

        # Try a boosted query to verify it still works.
        eq_(len(self.get_s().query(height__range=(5, 7))
                            .boost(height__range=100)), 3)
示例#6
0
    def test_q_mixed(self):
        q1 = Q(foo__text='should', bar__text='should', should=True)
        q2 = Q(baz='must')
        q3 = Q(bat='must_not', must_not=True)
        q4 = Q(ban='must', must=True)
        q5 = Q(bam='must', must=True)

        q_all = q1 + q2 + q3 + q4 + q5

        eq_(sorted(q_all.should_q),
            [('bar__text', 'should'), ('foo__text', 'should')])

        eq_(sorted(q_all.must_q),
            [('bam', 'must'), ('ban', 'must'), ('baz', 'must')])

        eq_(sorted(q_all.must_not_q),
            [('bat', 'must_not')])
示例#7
0
    def test_q_match_phrase(self):
        # Doing a match query for the two words in either order kicks up
        # two results.
        eq_(len(self.get_s().query(foo__match='train car')), 2)
        eq_(len(self.get_s().query(foo__match='car train')), 2)

        eq_(len(self.get_s().query(Q(foo__match='train car'))), 2)
        eq_(len(self.get_s().query(Q(foo__match='car train'))), 2)

        # Doing a match_phrase query for the two words in the right
        # order kicks up one result.
        eq_(len(self.get_s().query(foo__match_phrase='train car')), 1)

        eq_(len(self.get_s().query(Q(foo__match_phrase='train car'))), 1)

        # Doing a match_phrase query for the two words in the wrong
        # order kicks up no results.
        eq_(len(self.get_s().query(foo__match_phrase='car train')), 0)

        eq_(len(self.get_s().query(Q(foo__match_phrase='car train'))), 0)
示例#8
0
    def test_q_order(self):
        q1 = Q(foo__text='abc') + Q(bar__text='def')

        q2 = Q(bar__text='def') + Q(foo__text='abc')
        eq_(q1, q2)

        q2 = Q(bar__text='def')
        q2 += Q(foo__text='abc')
        eq_(q1, q2)

        q2 = Q(foo__text='abc')
        q2 += Q(bar__text='def')
        eq_(q1, q2)
示例#9
0
    def test_q_demote(self):
        s = self.get_s().query(foo__text='car')
        scores = [(sr['id'], sr._score) for sr in s.values_dict('id')]

        s = s.demote(0.5, width__term='5')
        demoted_scores = [(sr['id'], sr._score) for sr in s.values_dict('id')]

        # These are both sorted by scores. We're demoting one result
        # so the top result in each list is different.
        assert scores[0] != demoted_scores

        # Now we do the whole thing again with Qs.
        s = self.get_s().query(Q(foo__text='car'))
        scores = [(sr['id'], sr._score) for sr in s.values_dict('id')]

        s = s.demote(0.5, Q(width__term='5'))
        demoted_scores = [(sr['id'], sr._score) for sr in s.values_dict('id')]

        # These are both sorted by scores. We're demoting one result
        # so the top result in each list is different.
        assert scores[0] != demoted_scores
示例#10
0
    def filter_queryset(self, request, queryset, view):
        search_param = request.QUERY_PARAMS.get(self.search_param, None)

        if search_param:
            queries = {}
            boosts = {}
            for operation, boost in self.search_operations:
                queries[operation] = search_param
                boosts[operation] = boost
            queryset = (queryset.query(Q(should=True,
                                         **queries)).boost(**boosts))
        if flag_is_active(request, 'search_explanation'):
            queryset = queryset.explain()  # adds scoring explaination
        return queryset
示例#11
0
    def filter_queryset(self, request, queryset, view):
        queries = {}
        boosts = {}

        for name in self.search_params:

            search_param = request.QUERY_PARAMS.get(name, None)
            if not search_param:
                continue

            for operation_tmpl, boost in self.search_operations:
                operation = operation_tmpl % name
                queries[operation] = search_param.lower()
                boosts[operation] = boost

        queryset = (queryset.query(Q(should=True, **queries)).boost(**boosts))

        return queryset
示例#12
0
    def test_boost(self):
        """Boosted queries shouldn't raise a SearchPhaseExecutionException."""
        q1 = (self.get_s()
                  .boost(foo=4.0)
                  .query(foo='car', foo__text='car', foo__text_phrase='car'))

        # Make sure the query executes without throwing an exception.
        list(q1)

        # Verify it's producing the correct query.
        eq_(q1._build_query(),
            {
                'query': {
                    'bool': {
                        'must': [
                            {'text_phrase': {'foo': {'query': 'car', 'boost': 4.0}}},
                            {'term': {'foo': {'value': 'car', 'boost': 4.0}}},
                            {'text': {'foo': {'query': 'car', 'boost': 4.0}}}
                        ]
                    }
                }
            })

        # Do the same thing with Qs.
        q1 = (self.get_s()
                  .boost(foo=4.0)
                  .query(Q(foo='car', foo__text='car', foo__text_phrase='car')))

        # Make sure the query executes without throwing an exception.
        list(q1)

        # Verify it's producing the correct query.
        eq_(q1._build_query(),
            {
                'query': {
                    'bool': {
                        'must': [
                            {'text_phrase': {'foo': {'query': 'car', 'boost': 4.0}}},
                            {'term': {'foo': {'value': 'car', 'boost': 4.0}}},
                            {'text': {'foo': {'query': 'car', 'boost': 4.0}}}
                        ]
                    }
                }
            })
示例#13
0
 def test_q_must_should(self):
     with self.assertRaises(InvalidFlagsError):
         Q(foo__text='abc', must=True, should=True)
示例#14
0
 def test_q_must_not(self):
     q = Q(foo__text='abc', bar__text='def', must_not=True)
     eq_(sorted(q.should_q), [])
     eq_(sorted(q.must_q), [])
     eq_(sorted(q.must_not_q), [('bar__text', 'def'), ('foo__text', 'abc')])
示例#15
0
    def test_boolean_query_compled(self):
        """Verify that should/must/must_not collapses right"""
        s = self.get_s()

        eq_((s.query(Q(foo='should', should=True),
                     bar='must')
             ._build_query()),
            {
                'query': {
                    'bool': {
                        'should': [
                            {'term': {'foo': 'should'}}
                        ],
                        'must': [
                            {'term': {'bar': 'must'}}
                        ]
                    }
                }
            })

        eq_((s.query(Q(foo='should', should=True),
                     bar='must_not', must_not=True)
             ._build_query()),
            {
                'query': {
                    'bool': {
                        'should': [
                            {'term': {'foo': 'should'}}
                        ],
                        'must_not': [
                            {'term': {'bar': 'must_not'}}
                        ]
                    }
                }
            })

        eq_((s.query(Q(foo='should', should=True),
                     bar='must_not', must_not=True)
             .query(Q(baz='must'))
             ._build_query()),
            {
                'query': {
                    'bool': {
                        'should': [
                            {'term': {'foo': 'should'}},
                        ],
                        'must_not': [
                            {'term': {'bar': 'must_not'}}
                        ],
                        'must': [
                            {'term': {'baz': 'must'}}
                        ]
                    }
                }
            })

        # This is a pathological case. The should=True applies to the
        # foo term query and the must=True doesn't apply to
        # anything--it shouldn't override the should=True in the Q.
        eq_((s.query(Q(foo='should', should=True), must=True)
             ._build_query()),
            {
                'query': {
                    'bool': {
                        'should': [
                            {'term': {'foo': 'should'}}
                        ]
                    }
                }
            })
示例#16
0
    def test_q_bad_field_action(self):
        with self.assertRaises(InvalidFieldActionError):
            len(self.get_s().query(foo__foo='awesome'))

        with self.assertRaises(InvalidFieldActionError):
            len(self.get_s().query(Q(foo__foo='awesome')))
示例#17
0
    def test_q_terms(self):
        eq_(len(self.get_s().query(foo__terms=['car', 'duck'])), 3)

        eq_(len(self.get_s().query(Q(foo__terms=['car', 'duck']))), 3)
示例#18
0
    def test_q_wildcard(self):
        eq_(len(self.get_s().query(foo__wildcard='tra*n')), 1)
        eq_(len(self.get_s().query(foo__wildcard='tra?n')), 1)

        eq_(len(self.get_s().query(Q(foo__wildcard='tra*n'))), 1)
        eq_(len(self.get_s().query(Q(foo__wildcard='tra?n'))), 1)
示例#19
0
    def test_q(self):
        eq_(len(self.get_s().query(foo='bar')), 1)
        eq_(len(self.get_s().query(foo='car')), 2)

        eq_(len(self.get_s().query(Q(foo='bar'))), 1)
        eq_(len(self.get_s().query(Q(foo='car'))), 2)
示例#20
0
    def cookbooth_search(cls, search_str, fields=None, hide_for_sale=False):
        search_str = search_str.lower() if search_str else ""

        fields = fields or []
        q = Q()

        if hide_for_sale:
            q += Q(forSale=False)

        if not fields or ('recipe' in fields and 'chef' in fields
                          and 'book' in fields and 'ingredient' in fields):
            q += Q(name__query_string=search_str, should=True)
            q += Q(tagNames__query_string=search_str, should=True)
            q += Q(chefName__query_string=search_str, should=True)
            q += Q(bookNames__query_string=search_str, should=True)
            q += Q(ingredientNames__query_string=search_str, should=True)
        else:
            if 'recipe' in fields:
                q += Q(name__query_string=search_str, should=True)
                q += Q(tagNames__query_string=search_str, should=True)

            if 'chef' in fields:
                q += Q(chefName__query_string=search_str, should=True)

            if 'book' in fields:
                q += Q(bookNames__query_string=search_str, should=True)
                q += Q(tagNames__query_string=search_str, should=True)

            if 'ingredient' in fields:
                q += Q(ingredientNames__query_string=search_str, should=True)
                q += Q(tagNames__query_string=search_str, should=True)

        searcher = cls.search()
        searcher = searcher.boost(name=8.0, chefName=4.0, ingredientNames=6.0)
        qry = searcher.query(q)[:240]

        return qry
示例#21
0
    def test_q_prefix(self):
        eq_(len(self.get_s().query(foo__prefix='ca')), 2)
        eq_(len(self.get_s().query(foo__startswith='ca')), 2)

        eq_(len(self.get_s().query(Q(foo__prefix='ca'))), 2)
        eq_(len(self.get_s().query(Q(foo__startswith='ca'))), 2)
示例#22
0
    def test_q_match(self):
        eq_(len(self.get_s().query(foo__match='car')), 2)

        eq_(len(self.get_s().query(Q(foo__match='car'))), 2)
示例#23
0
    def test_q_text(self):
        eq_(len(self.get_s().query(foo__text='car')), 2)

        eq_(len(self.get_s().query(Q(foo__text='car'))), 2)
示例#24
0
 def cookbooth_search(cls, search_str):
     search_str = '*%s*' % search_str
     q = Q(_all__query_string=search_str, should=True)
     searcher = cls.search()
     return searcher.query(q)
示例#25
0
    def test_q_in(self):
        eq_(len(self.get_s().query(foo__in=['car', 'bar'])), 3)

        eq_(len(self.get_s().query(Q(foo__in=['car', 'bar']))), 3)