def _matcher(self, matchercls, q_weight_fn, searcher, weighting=None, **kwargs): # q_weight_fn is a function which is called on each query and returns a # "weight" value which is used to build a huffman-like matcher tree. If # q_weight_fn is None, an order-preserving binary tree is used instead. # Pull any queries inside a Not() out into their own list subs, nots = self._split_queries() if not subs: return matching.NullMatcher() # Create a matcher from the list of subqueries subms = [q.matcher(searcher, weighting=weighting) for q in subs] if len(subms) == 1: m = subms[0] elif q_weight_fn is None: m = make_binary_tree(matchercls, subms) else: w_subms = [(q_weight_fn(q), m) for q, m in zip(subs, subms)] m = make_weighted_tree(matchercls, w_subms) # If there were queries inside Not(), make a matcher for them and # wrap the matchers in an AndNotMatcher if nots: if len(nots) == 1: notm = nots[0].matcher(searcher) else: r = searcher.reader() notms = [(q.estimate_size(r), q.matcher(searcher)) for q in nots] notm = make_weighted_tree(matching.UnionMatcher, notms) if notm.is_active(): m = matching.AndNotMatcher(m, notm) # If this query had a boost, add a wrapping matcher to apply the boost if self.boost != 1.0: m = matching.WrappingMatcher(m, self.boost) return m
def _tree_matcher(self, subs, mcls, searcher, context, q_weight_fn, **kwargs): # q_weight_fn is a function which is called on each query and returns a # "weight" value which is used to build a huffman-like matcher tree. If # q_weight_fn is None, an order-preserving binary tree is used instead. # Create a matcher from the list of subqueries subms = [q.matcher(searcher, context) for q in subs] if len(subms) == 1: m = subms[0] elif q_weight_fn is None: m = make_binary_tree(mcls, subms, **kwargs) else: w_subms = [(q_weight_fn(q), m) for q, m in zip(subs, subms)] m = make_weighted_tree(mcls, w_subms, **kwargs) # If this query had a boost, add a wrapping matcher to apply the boost if self.boost != 1.0: m = matching.WrappingMatcher(m, self.boost) return m