blob: fb16ff935b08a8d947cfceb53aaa50b8a0cb2702 [file] [log] [blame]
Nils Diewaldf399a672013-11-18 17:55:22 +00001package de.ids_mannheim.korap.query;
2
3// Based on SpanNearQuery
4import java.io.IOException;
Nils Diewaldf399a672013-11-18 17:55:22 +00005import java.util.Map;
6import java.util.Set;
7
Nils Diewaldf399a672013-11-18 17:55:22 +00008import org.apache.lucene.index.IndexReader;
Eliza Margarethadc98dc12016-11-16 14:33:42 +01009import org.apache.lucene.index.LeafReaderContext;
Nils Diewaldf399a672013-11-18 17:55:22 +000010import org.apache.lucene.index.Term;
11import org.apache.lucene.index.TermContext;
Nils Diewald93d6d1b2015-02-02 21:47:43 +000012import org.apache.lucene.search.Query;
13import org.apache.lucene.search.spans.SpanQuery;
Nils Diewaldf399a672013-11-18 17:55:22 +000014import org.apache.lucene.search.spans.Spans;
Nils Diewald93d6d1b2015-02-02 21:47:43 +000015import org.apache.lucene.util.Bits;
16import org.apache.lucene.util.ToStringUtils;
Nils Diewaldf399a672013-11-18 17:55:22 +000017
18import de.ids_mannheim.korap.query.spans.WithinSpans;
Nils Diewaldf399a672013-11-18 17:55:22 +000019
Nils Diewald93d6d1b2015-02-02 21:47:43 +000020
Nils Diewaldf399a672013-11-18 17:55:22 +000021/**
22 * Matches spans that are within certain elements.
23 */
24public class SpanWithinQuery extends SpanQuery implements Cloneable {
25 private SpanQuery wrap;
26 private SpanQuery embedded;
27 public String field;
Nils Diewald6802acd2014-03-18 18:29:30 +000028 private byte flag;
Nils Diewaldf399a672013-11-18 17:55:22 +000029 private boolean collectPayloads;
30
Nils Diewaldbb33da22015-03-04 16:24:25 +000031 public static final byte OVERLAP = WithinSpans.OVERLAP,
32 REAL_OVERLAP = WithinSpans.REAL_OVERLAP,
33 WITHIN = WithinSpans.WITHIN, REAL_WITHIN = WithinSpans.REAL_WITHIN,
34 ENDSWITH = WithinSpans.ENDSWITH,
35 STARTSWITH = WithinSpans.STARTSWITH, MATCH = WithinSpans.MATCH;
36
Nils Diewaldf399a672013-11-18 17:55:22 +000037
38 // may support "starting" and "ending"
39
Nils Diewald93d6d1b2015-02-02 21:47:43 +000040
Nils Diewaldf399a672013-11-18 17:55:22 +000041 // Constructor
Nils Diewaldbb33da22015-03-04 16:24:25 +000042 public SpanWithinQuery (SpanQuery wrap, SpanQuery embedded, byte flag,
Nils Diewald93d6d1b2015-02-02 21:47:43 +000043 boolean collectPayloads) {
Nils Diewaldf399a672013-11-18 17:55:22 +000044
Nils Diewald93d6d1b2015-02-02 21:47:43 +000045 this.field = embedded.getField();
46 this.embedded = embedded;
47 this.wrap = wrap;
48 this.flag = flag;
49 this.collectPayloads = collectPayloads;
Nils Diewaldf399a672013-11-18 17:55:22 +000050 };
51
52
53 // Constructor
Nils Diewaldbb33da22015-03-04 16:24:25 +000054 public SpanWithinQuery (String element, SpanQuery embedded) {
Nils Diewald93d6d1b2015-02-02 21:47:43 +000055 this(element, embedded, WITHIN, true);
Nils Diewaldf399a672013-11-18 17:55:22 +000056 };
57
Nils Diewald93d6d1b2015-02-02 21:47:43 +000058
Nils Diewaldf399a672013-11-18 17:55:22 +000059 // Constructor
Nils Diewaldbb33da22015-03-04 16:24:25 +000060 public SpanWithinQuery (String element, SpanQuery embedded, byte flag,
Nils Diewald93d6d1b2015-02-02 21:47:43 +000061 boolean collectPayloads) {
Nils Diewaldbb33da22015-03-04 16:24:25 +000062 this((SpanQuery) new SpanElementQuery(embedded.getField(), element),
63 embedded, flag, collectPayloads);
Nils Diewald93d6d1b2015-02-02 21:47:43 +000064 };
65
66
67 // Constructor
Nils Diewaldbb33da22015-03-04 16:24:25 +000068 public SpanWithinQuery (String element, SpanQuery embedded, byte flag) {
Nils Diewald93d6d1b2015-02-02 21:47:43 +000069 this(element, embedded, flag, true);
70 };
71
72
73 // Constructor
Nils Diewaldbb33da22015-03-04 16:24:25 +000074 public SpanWithinQuery (String element, SpanQuery embedded,
Nils Diewald93d6d1b2015-02-02 21:47:43 +000075 boolean collectPayloads) {
76 this(element, embedded, WITHIN, collectPayloads);
Nils Diewaldf399a672013-11-18 17:55:22 +000077 };
78
79
80 // Constructor
Nils Diewaldbb33da22015-03-04 16:24:25 +000081 public SpanWithinQuery (SpanQuery wrap, SpanQuery embedded, byte flag) {
Nils Diewald93d6d1b2015-02-02 21:47:43 +000082 this(wrap, embedded, flag, true);
Nils Diewaldf399a672013-11-18 17:55:22 +000083 };
84
Nils Diewald93d6d1b2015-02-02 21:47:43 +000085
Nils Diewaldf399a672013-11-18 17:55:22 +000086 // Constructor
Nils Diewaldbb33da22015-03-04 16:24:25 +000087 public SpanWithinQuery (SpanQuery wrap, SpanQuery embedded) {
Nils Diewald93d6d1b2015-02-02 21:47:43 +000088 this(wrap, embedded, WITHIN, true);
Nils Diewaldf399a672013-11-18 17:55:22 +000089 };
90
91
92 @Override
Nils Diewaldbb33da22015-03-04 16:24:25 +000093 public String getField () {
94 return field;
95 };
Nils Diewald93d6d1b2015-02-02 21:47:43 +000096
Nils Diewaldbb33da22015-03-04 16:24:25 +000097
98 public SpanQuery wrap () {
99 return wrap;
100 };
101
102
103 public SpanQuery embedded () {
104 return embedded;
105 };
106
107
108 public byte flag () {
109 return flag;
110 };
111
112
Nils Diewaldf399a672013-11-18 17:55:22 +0000113 @Override
Nils Diewaldbb33da22015-03-04 16:24:25 +0000114 public void extractTerms (Set<Term> terms) {
Nils Diewald93d6d1b2015-02-02 21:47:43 +0000115 embedded.extractTerms(terms);
Nils Diewaldf399a672013-11-18 17:55:22 +0000116 };
Nils Diewaldbb33da22015-03-04 16:24:25 +0000117
Nils Diewald93d6d1b2015-02-02 21:47:43 +0000118
Nils Diewaldf399a672013-11-18 17:55:22 +0000119 @Override
Nils Diewaldbb33da22015-03-04 16:24:25 +0000120 public String toString (String field) {
Nils Diewald93d6d1b2015-02-02 21:47:43 +0000121 StringBuilder buffer = new StringBuilder();
122 buffer.append("span");
123 buffer.append(flagToString());
124 buffer.append("(");
Nils Diewaldf399a672013-11-18 17:55:22 +0000125 buffer.append(wrap.toString());
126 buffer.append(", ");
Nils Diewald93d6d1b2015-02-02 21:47:43 +0000127 buffer.append(embedded.toString(field));
128 buffer.append(")");
129 buffer.append(ToStringUtils.boost(getBoost()));
130 return buffer.toString();
Nils Diewaldf399a672013-11-18 17:55:22 +0000131 };
Nils Diewaldbb33da22015-03-04 16:24:25 +0000132
Nils Diewald93d6d1b2015-02-02 21:47:43 +0000133
Nils Diewald6802acd2014-03-18 18:29:30 +0000134 private String flagToString () {
Nils Diewald93d6d1b2015-02-02 21:47:43 +0000135 switch (flag) {
Nils Diewaldbb33da22015-03-04 16:24:25 +0000136 case OVERLAP:
137 return "Overlap";
138 case REAL_OVERLAP:
139 return "OverlapStrict";
140 case WITHIN:
141 return "Contain";
142 case REAL_WITHIN:
143 return "ContainStrict";
144 case ENDSWITH:
145 return "EndsWith";
146 case STARTSWITH:
147 return "StartsWith";
148 case MATCH:
149 return "Match";
Nils Diewald93d6d1b2015-02-02 21:47:43 +0000150 };
151 return "Contains";
Nils Diewald6802acd2014-03-18 18:29:30 +0000152 };
Nils Diewaldf399a672013-11-18 17:55:22 +0000153
Nils Diewald93d6d1b2015-02-02 21:47:43 +0000154
Nils Diewaldf399a672013-11-18 17:55:22 +0000155 @Override
Akron700c1eb2015-09-25 16:57:30 +0200156 public Spans getSpans (final LeafReaderContext context, Bits acceptDocs,
Nils Diewaldbb33da22015-03-04 16:24:25 +0000157 Map<Term, TermContext> termContexts) throws IOException {
158 return (Spans) new WithinSpans(this, context, acceptDocs, termContexts,
159 this.flag);
Nils Diewaldf399a672013-11-18 17:55:22 +0000160 };
Nils Diewaldbb33da22015-03-04 16:24:25 +0000161
Nils Diewaldf399a672013-11-18 17:55:22 +0000162
Nils Diewaldea125202014-09-19 15:12:06 +0000163 /*
164 * Rewrite query in case it includes regular expressions or wildcards
165 */
Nils Diewaldf399a672013-11-18 17:55:22 +0000166 @Override
167 public Query rewrite (IndexReader reader) throws IOException {
Nils Diewald93d6d1b2015-02-02 21:47:43 +0000168 SpanWithinQuery clone = null;
Nils Diewaldf399a672013-11-18 17:55:22 +0000169
Nils Diewald93d6d1b2015-02-02 21:47:43 +0000170 // Does the embedded query needs a rewrite?
171 SpanQuery query = (SpanQuery) embedded.rewrite(reader);
172 if (query != embedded) {
173 if (clone == null)
174 clone = this.clone();
175 clone.embedded = query;
176 };
Nils Diewaldf399a672013-11-18 17:55:22 +0000177
Nils Diewald93d6d1b2015-02-02 21:47:43 +0000178 // Does the wrap query needs a rewrite?
179 query = (SpanQuery) wrap.rewrite(reader);
180 if (query != wrap) {
181 if (clone == null)
182 clone = this.clone();
183 clone.wrap = query;
184 };
Nils Diewaldea125202014-09-19 15:12:06 +0000185
Nils Diewald93d6d1b2015-02-02 21:47:43 +0000186 // There is a clone and it is important
187 if (clone != null)
188 return clone;
Nils Diewaldf399a672013-11-18 17:55:22 +0000189
Nils Diewald93d6d1b2015-02-02 21:47:43 +0000190 return this;
Nils Diewaldf399a672013-11-18 17:55:22 +0000191 };
Nils Diewaldbb33da22015-03-04 16:24:25 +0000192
Nils Diewaldf399a672013-11-18 17:55:22 +0000193
194 @Override
195 public SpanWithinQuery clone () {
Nils Diewald93d6d1b2015-02-02 21:47:43 +0000196 SpanWithinQuery spanWithinQuery = new SpanWithinQuery(
Nils Diewaldbb33da22015-03-04 16:24:25 +0000197 (SpanQuery) wrap.clone(), (SpanQuery) embedded.clone(),
198 this.flag, this.collectPayloads);
Nils Diewald93d6d1b2015-02-02 21:47:43 +0000199 spanWithinQuery.setBoost(getBoost());
200 return spanWithinQuery;
Nils Diewaldf399a672013-11-18 17:55:22 +0000201 };
202
203
Nils Diewald93d6d1b2015-02-02 21:47:43 +0000204 /**
205 * Returns true iff <code>o</code> is equal to this.
206 */
Nils Diewaldf399a672013-11-18 17:55:22 +0000207 @Override
Nils Diewaldbb33da22015-03-04 16:24:25 +0000208 public boolean equals (Object o) {
209 if (this == o)
210 return true;
211 if (!(o instanceof SpanWithinQuery))
212 return false;
213
Nils Diewald93d6d1b2015-02-02 21:47:43 +0000214 final SpanWithinQuery spanWithinQuery = (SpanWithinQuery) o;
Nils Diewaldbb33da22015-03-04 16:24:25 +0000215
216 if (collectPayloads != spanWithinQuery.collectPayloads)
217 return false;
218 if (!wrap.equals(spanWithinQuery.wrap))
219 return false;
220 if (!embedded.equals(spanWithinQuery.embedded))
221 return false;
222
Nils Diewald93d6d1b2015-02-02 21:47:43 +0000223 return getBoost() == spanWithinQuery.getBoost();
Nils Diewaldf399a672013-11-18 17:55:22 +0000224 };
225
Nils Diewald93d6d1b2015-02-02 21:47:43 +0000226
Nils Diewaldf399a672013-11-18 17:55:22 +0000227 // I don't know what I am doing here
228 @Override
Nils Diewaldbb33da22015-03-04 16:24:25 +0000229 public int hashCode () {
Nils Diewald93d6d1b2015-02-02 21:47:43 +0000230 int result = flag;
231 result = embedded.hashCode();
232 result += wrap.hashCode();
233 result ^= (result << 4) | (result >>> 29);
234 result += Float.floatToRawIntBits(getBoost());
235 return result;
Nils Diewaldf399a672013-11-18 17:55:22 +0000236 };
237};