1 package org.wikimedia.search.extra.regex;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import org.apache.lucene.index.Term;
7 import org.apache.lucene.search.BooleanClause.Occur;
8 import org.apache.lucene.search.BooleanQuery;
9 import org.apache.lucene.search.Query;
10 import org.apache.lucene.search.TermInSetQuery;
11 import org.apache.lucene.search.TermQuery;
12 import org.apache.lucene.util.BytesRef;
13 import org.wikimedia.search.extra.regex.expression.Expression;
14
15 import com.google.common.collect.ImmutableSet;
16
17
18
19
20 public class ExpressionToQueryTransformer implements Expression.Transformer<String, Query> {
21 private final String ngramField;
22
23 public ExpressionToQueryTransformer(String ngramField) {
24 this.ngramField = ngramField;
25 }
26
27 @Override
28 public Query alwaysTrue() {
29 throw new InvalidRegexException("Can't transform always true into a query.");
30 }
31
32 @Override
33 public Query alwaysFalse() {
34 throw new InvalidRegexException("Can't transform always false into a query.");
35 }
36
37 @Override
38 public Query leaf(String t) {
39 return new TermQuery(new Term(ngramField, t));
40 }
41
42 @Override
43 public Query and(ImmutableSet<Query> js) {
44 BooleanQuery.Builder builder = new BooleanQuery.Builder();
45
46 for (Query j : js) {
47 builder.add(j, Occur.FILTER);
48 }
49 return builder.build();
50 }
51
52 @Override
53 public Query or(ImmutableSet<Query> js) {
54
55 boolean allTermQueries = true;
56 List<BytesRef> allTerms = null;
57 BooleanQuery.Builder builder = new BooleanQuery.Builder();
58 for (Query j : js) {
59 builder.add(j, Occur.SHOULD);
60 if (allTermQueries) {
61 allTermQueries = j instanceof TermQuery;
62 if (allTermQueries) {
63 if (allTerms == null) {
64 allTerms = new ArrayList<>(js.size());
65 }
66 allTerms.add(((TermQuery) j).getTerm().bytes());
67 }
68 }
69 }
70 if (!allTermQueries) {
71 return builder.build();
72 }
73 assert allTerms != null;
74 return new TermInSetQuery(ngramField, allTerms);
75 }
76 }