def _get_filter_expression(self, attr_id: int, values) -> t.Optional[Expression]: w = [ merge_attr_value_int(attr_id, v) for v in self._parse_values(values, 'exact') ] if not w: return None if len(w) == 1: return Term(self.field, w[0]) return Terms(self.field, w)
def test_attr_bool_simple_filter(compiler): qf = QueryFilter() qf.add_filter( AttrBoolSimpleFilter('attr_bool', Field('attr.bool'), alias='a')) sq = qf.apply(SearchQuery(), {}) assert sq.to_dict(compiler=compiler) == {} sq = qf.apply(SearchQuery(), {'a1': 'true'}) assert sq.to_dict(compiler=compiler) == (SearchQuery().filter( Term('attr.bool', 0x3)).to_dict(compiler=compiler)) sq = qf.apply(SearchQuery(), {'a1': 'True'}) assert sq.to_dict(compiler=compiler) == (SearchQuery().filter( Term('attr.bool', 0x3)).to_dict(compiler=compiler)) sq = qf.apply(SearchQuery(), {'a1': [True]}) assert sq.to_dict(compiler=compiler) == (SearchQuery().filter( Term('attr.bool', 0x3)).to_dict(compiler=compiler)) sq = qf.apply(SearchQuery(), {'a1': 'False'}) assert sq.to_dict(compiler=compiler) == (SearchQuery().filter( Term('attr.bool', 0x2)).to_dict(compiler=compiler)) sq = qf.apply(SearchQuery(), {'a1': ['true', 'false']}) assert sq.to_dict(compiler=compiler) == (SearchQuery().filter( Terms('attr.bool', [0x3, 0x2])).to_dict(compiler=compiler)) sq = qf.apply(SearchQuery(), {'a1': ['true', 'false'], 'a2': 'false'}) assert sq.to_dict(compiler=compiler) == (SearchQuery().filter( Terms('attr.bool', [0x3, 0x2])).filter(Term('attr.bool', 0x4)).to_dict(compiler=compiler)) sq = qf.apply(SearchQuery(), {'a2147483648': '1'}) assert sq.to_dict(compiler=compiler) == {} sq = qf.apply(SearchQuery(), {'a1': 'TRUE'}) assert sq.to_dict(compiler=compiler) == {}
def test_expression(self): f = DynamicDocument.fields e = Params({'foo': 'bar'}) self.assert_expression( e, {"foo": "bar"} ) self.assertEqual(e['foo'], 'bar') self.assertTrue('foo' in e) self.assert_expression( Match(f.message, 'this is a test'), { "match": { "message": "this is a test", } } ) self.assert_expression( Match( f.message, 'this is a test', minimum_should_match='100%', cutoff_frequency=0.001, boost=2.1 ), { "match": { "message": { "query": "this is a test", "minimum_should_match": "100%", "cutoff_frequency": 0.001, "boost": 2.1, } } } ) self.assert_expression( Term(f.user, 'kimchy'), { "term": {"user": "******"} } ) self.assert_expression( Term(f.user, 'kimchy', boost=1.2), { "term": {"user": {"value": "kimchy", "boost": 1.2}} } ) self.assert_expression( Term('user.login', 'kimchy'), { "term": {"user.login": "******"} } ) self.assert_expression( Terms(f.status, [0]), { "terms": { "status": [0] } } ) self.assert_expression( Terms(f.tags, ['blue', 'pill'], minimum_should_match=1), { "terms": { "tags": ["blue", "pill"], "minimum_should_match": 1 } } ) self.assert_expression( Exists(f.tags), { "exists": {"field": "tags"} } ) self.assert_expression( Missing(f.tags, _cache=True), { "missing": { "field": "tags", "_cache": True } } ) self.assert_expression( Bool( must=Term(f.user, 'kimchy'), filter=Term(f.tag, 'tech'), must_not=Range(f.age, from_=10, to=20), should=[Term(f.tag, 'wow'), Term(f.tag, 'elasticsearch', boost=2.1)], minimum_should_match=1, boost=1.0, ), { "bool": { "must": { "term": {"user": "******"} }, "filter": { "term": {"tag": "tech"} }, "must_not": { "range": { "age": {"from": 10, "to": 20} } }, "should": [ { "term": {"tag": "wow"} }, { "term": {"tag": {"value": "elasticsearch", "boost": 2.1}} } ], "minimum_should_match": 1, "boost": 1.0 } } ) e = MultiMatch( "Will Smith", [self.index.star.title.boost(4), self.index.star.wildcard('*_name').boost(2)], minimum_should_match='100%' ) self.assert_expression( e, { "multi_match": { "query": "Will Smith", "fields": ["title^4", "*_name^2"], "minimum_should_match": "100%" } } ) self.assertEqual( e._collect_doc_classes(), {self.index.star} ) self.assert_expression( Range(self.index.product.price, lte=100, boost=2.2, execution='index', _cache=False), { "range": { "price": {"lte": 100, "boost": 2.2}, "execution": "index", "_cache": False } } ) self.assert_expression( Boosting( positive=Term(f.field1, 'value1'), negative=Term(f.field2, 'value2'), negative_boost=0.2 ), { "boosting": { "positive": { "term": { "field1": "value1" } }, "negative": { "term": { "field2": "value2" } }, "negative_boost": 0.2 } } ) self.assert_expression( Common( f.body, 'nelly the elephant not as a cartoon', cutoff_frequency=0.001, minimum_should_match=dict(low_freq=2, high_freq=3), ), { "common": { "body": { "query": "nelly the elephant not as a cartoon", "cutoff_frequency": 0.001, "minimum_should_match": { "low_freq": 2, "high_freq": 3 } } } } ) self.assert_expression( ConstantScore(filter=Term(f.user, 'kimchy'), boost=1.2), { "constant_score": { "filter": { "term": { "user": "******"} }, "boost": 1.2 } } ) self.assert_expression( FunctionScore( query=MatchAll(), field_value_factor={ 'field': f.popularity, 'factor': 1.2, 'modifier': 'sqrt', } ), { "function_score": { "query": {"match_all": {}}, "field_value_factor": { "field": "popularity", "factor": 1.2, "modifier": "sqrt" } } } ) self.assert_expression( DisMax([Term(f.age, 34), Term(f.age, 35)], boost=1.2, tie_breaker=0.7), { "dis_max": { "tie_breaker": 0.7, "boost": 1.2, "queries": [ { "term" : { "age" : 34 } }, { "term" : { "age" : 35 } } ] } } ) self.assert_expression( Filtered( filter=Range(f.created, gte='now - 1d / d'), query=Match(f.tweet, 'full text search') ), { "filtered": { "query": { "match": { "tweet": "full text search" } }, "filter": { "range": { "created": { "gte": "now - 1d / d" }} } } } ) self.assert_expression( Ids(['123456']), { "ids": { "values": ["123456"] } } ) self.assert_expression( Ids(['1', '4', '100'], type="my_type"), { "ids": { "type": "my_type", "values": ["1", "4", "100"] } } ) self.assert_expression( Prefix(f.user, 'ki', boost=2.0), { "prefix": { "user": { "value": "ki", "boost": 2.0 } } } ) self.assert_expression( MatchAll(), {"match_all": {}} ) self.assert_expression( MatchAll(boost=1.2), { "match_all": { "boost" : 1.2 } } ) self.assert_expression( Query(Match(f.title, 'this that thus')), { "query": { "match": { "title": "this that thus" } } } ) self.assert_expression( Query(Match(f.title, 'this that thus'), _cache=True), { "fquery": { "query": { "match": { "title": "this that thus" } }, "_cache": True } } ) self.assertRaises(NotImplementedError, BooleanExpression) self.assert_expression( And( Range(f.post_date, from_='2010-03-01', to='2010-04-01'), Prefix(f.name.second, 'ba') ), { "and": [ { "range": { "post_date": { "from": "2010-03-01", "to": "2010-04-01" } } }, { "prefix" : { "name.second" : "ba" } } ] } ) self.assert_expression( And( Range(f.post_date, from_='2010-03-01', to='2010-04-01'), Prefix(f.name.second, 'ba'), _cache=True ), { "and": { "filters": [ { "range": { "post_date": { "from": "2010-03-01", "to": "2010-04-01" } } }, { "prefix" : { "name.second" : "ba" } } ], "_cache": True } } ) self.assert_expression( Or(Term(f.name.second, 'banon'), Term(f.name.nick, 'kimchy')), { "or": [ { "term": {"name.second": "banon"} }, { "term": {"name.nick": "kimchy"} } ] } ) self.assert_expression( And(Or(Term(f.name.nick, 'kimchy'))), { "term": {"name.nick": "kimchy"} } ) self.assert_expression( Not( Range(f.post_date, from_='2010-03-01', to='2010-04-01'), ), { "not": { "range": { "post_date": { "from": "2010-03-01", "to": "2010-04-01" } } } } ) self.assert_expression( Not( Range(f.post_date, from_='2010-03-01', to='2010-04-01'), _cache=True, ), { "not": { "filter": { "range": { "post_date": { "from": "2010-03-01", "to": "2010-04-01" } } }, "_cache": True } } ) self.assert_expression( Sort(f.post_date), "post_date" ) self.assert_expression( Sort(f.age, 'desc'), { "age": "desc" } ) self.assert_expression( Sort(f.price, 'asc', mode='avg'), { "price": { "order": "asc", "mode": "avg" } } ) self.assert_expression( Sort( f.offer.price.sort, 'asc', mode='avg', nested_filter=Term(f.offer.color, 'blue') ), { "offer.price.sort": { "order": "asc", "mode": "avg", "nested_filter": { "term": {"offer.color": "blue"} } } } ) self.assert_expression( SpanFirst(SpanTerm(f.user, 'kimchy'), end=3), { "span_first": { "match": { "span_term": {"user": "******"} }, "end": 3 } } ) self.assert_expression( SpanMulti(Prefix(f.user, 'ki', boost=1.08)), { "span_multi": { "match": { "prefix": { "user": {"value": "ki", "boost": 1.08} } } } } ) self.assert_expression( SpanNear( [SpanTerm(f.field, 'value1'), SpanTerm(f.field, 'value2'), SpanTerm(f.field, 'value3')], slop=12, in_order=False, collect_payloads=False, ), { "span_near": { "clauses": [ {"span_term": {"field": "value1"}}, {"span_term": {"field": "value2"}}, {"span_term": {"field": "value3"}} ], "slop": 12, "in_order": False, "collect_payloads": False } } ) self.assert_expression( SpanNot( SpanTerm(f.field1, 'hoya'), SpanNear([SpanTerm(f.field1, 'la'), SpanTerm(f.field1, 'hoya')], slop=0, in_order=True), ), { "span_not": { "include": { "span_term": {"field1": "hoya"} }, "exclude": { "span_near": { "clauses": [ {"span_term": {"field1": "la"}}, {"span_term": {"field1": "hoya"}} ], "slop": 0, "in_order": True } } } } ) self.assert_expression( SpanOr( [ SpanTerm(f.field, 'value1'), SpanTerm(f.field, 'value2'), SpanTerm(f.field, 'value3') ], boost=2, ), { "span_or": { "clauses": [ {"span_term": {"field": "value1"}}, {"span_term": {"field": "value2"}}, {"span_term": {"field": "value3"}} ], "boost": 2 } } ) self.assert_expression( Limit(1000), { "limit": { "value": 1000 } } ) e = Nested( self.index.movie.stars, Match(self.index.movie.stars.full_name, 'Will Smith'), score_mode='max', ) self.assert_expression( e, { "nested": { "path": "stars", "query": { "match": { "stars.full_name": "Will Smith" } }, "score_mode": "max" } } ) self.assertEqual( e._collect_doc_classes(), {self.index.movie} ) e = HasParent( self.index.blog.tag == 'something', parent_type=self.index.blog, score_mode='score', ) self.assert_expression( e, { "has_parent": { "parent_type": "blog", "query": { "term": { "tag": "something" } }, "score_mode": "score" } } ) self.assertEqual( e._collect_doc_classes(), set() ) e = HasParent( self.index.blog.tag == 'something', score_mode='score', ) self.assert_expression( e, { "has_parent": { "parent_type": "blog", "query": { "term": { "tag": "something" } }, "score_mode": "score" } } ) self.assertEqual( e._collect_doc_classes(), set() ) e = HasChild( self.index.blog_tag.tag == 'something', type=self.index.blog_tag, score_mode='sum', ) self.assert_expression( e, { "has_child": { "type": "blog_tag", "query": { "term": { "tag": "something" } }, "score_mode": "sum" } } ) self.assertEqual( e._collect_doc_classes(), set() ) e = HasChild( self.index.blog_tag.tag == 'something', score_mode='sum', ) self.assert_expression( e, { "has_child": { "type": "blog_tag", "query": { "term": { "tag": "something" } }, "score_mode": "sum" } } ) self.assertEqual( e._collect_doc_classes(), set() )
def test_attr_bool_facet_filter__multiple_selected_values(bool_qf, compiler): sq = bool_qf.apply(SearchQuery(), {'a1': ['true', 'false'], 'a2': 'true'}) assert sq.to_dict(compiler=compiler) == (SearchQuery().aggs({ 'qf.attr_bool.filter': agg.Filter( Bool.must( Terms('attr.bool', [0b11, 0b10]), Term('attr.bool', 0b101), ), aggs={'qf.attr_bool': agg.Terms(Field('attr.bool'), size=100)}), 'qf.attr_bool.filter:1': agg.Filter(Term('attr.bool', 0b101), aggs={ 'qf.attr_bool:1': agg.Terms(Field('attr.bool'), size=2, include=[0b10, 0b11]) }), 'qf.attr_bool.filter:2': agg.Filter(Terms('attr.bool', [0b11, 0b10]), aggs={ 'qf.attr_bool:2': agg.Terms(Field('attr.bool'), size=2, include=[0b100, 0b101]) }), }).post_filter( Bool.must( Terms('attr.bool', [0b11, 0b10]), Term('attr.bool', 0b101), )).to_dict(compiler=compiler)) qf_res = bool_qf.process_result( SearchResult( { 'aggregations': { 'qf.attr_bool.filter': { 'doc_count': 200, 'qf.attr_bool': { 'buckets': [ { 'key': 0b11, 'doc_count': 123, }, { 'key': 0b101, 'doc_count': 1 }, ] } }, 'qf.attr_bool.filter:1': { 'doc_count': 163, 'qf.attr_bool:1': { 'buckets': [ { 'key': 0b11, 'doc_count': 123, }, { 'key': 0b10, 'doc_count': 99 }, ] } }, 'qf.attr_bool.filter:2': { 'doc_count': 144, 'qf.attr_bool:2': { 'buckets': [ { 'key': 0b101, 'doc_count': 1 }, ] } }, } }, aggregations=sq.get_context().aggregations)) assert len(qf_res.attr_bool.facets) == 2 facet = qf_res.attr_bool.get_facet(1) assert len(facet.all_values) == 2 assert len(facet.selected_values) == 2 assert len(facet.values) == 0 assert facet.all_values[0] is facet.selected_values[0] assert facet.all_values[1] is facet.selected_values[1] assert facet.all_values[0].value is True assert facet.all_values[0].count == 123 assert facet.all_values[0].count_text == '123' assert facet.all_values[0].selected is True assert facet.all_values[1].value is False assert facet.all_values[1].count == 99 assert facet.all_values[1].count_text == '99' assert facet.all_values[1].selected is True facet = qf_res.attr_bool.get_facet(2) assert len(facet.all_values) == 1 assert len(facet.selected_values) == 1 assert len(facet.values) == 0 assert facet.all_values[0] is facet.selected_values[0] assert facet.all_values[0].value is True assert facet.all_values[0].count == 1 assert facet.all_values[0].count_text == '1' assert facet.all_values[0].selected is True