blob: fb0d3822c974148ee4022b544245c66c50c222ae [file] [log] [blame]
Nils Diewaldf399a672013-11-18 17:55:22 +00001package de.ids_mannheim.korap.query;
2
Nils Diewaldf399a672013-11-18 17:55:22 +00003import java.io.IOException;
Nils Diewaldf399a672013-11-18 17:55:22 +00004import java.util.Map;
Nils Diewaldf399a672013-11-18 17:55:22 +00005
Akron700c1eb2015-09-25 16:57:30 +02006import org.apache.lucene.index.LeafReaderContext;
Nils Diewald5871e4d2014-11-07 03:48:25 +00007import org.apache.lucene.index.IndexReader;
Nils Diewaldf399a672013-11-18 17:55:22 +00008import org.apache.lucene.index.Term;
9import org.apache.lucene.index.TermContext;
Eliza Margarethaf0171c52015-01-14 17:38:16 +000010import org.apache.lucene.search.Query;
Nils Diewaldf399a672013-11-18 17:55:22 +000011import org.apache.lucene.search.spans.SpanQuery;
Nils Diewaldf399a672013-11-18 17:55:22 +000012import org.apache.lucene.search.spans.Spans;
Eliza Margarethaf0171c52015-01-14 17:38:16 +000013import org.apache.lucene.search.spans.TermSpans;
Eliza Margaretha83b95372014-01-23 09:18:07 +000014import org.apache.lucene.util.Bits;
Eliza Margaretha609fcc62014-02-13 14:10:20 +000015import org.apache.lucene.util.ToStringUtils;
Nils Diewaldf399a672013-11-18 17:55:22 +000016
17import de.ids_mannheim.korap.query.spans.NextSpans;
18
Nils Diewald44d5fa12015-01-15 21:31:52 +000019/*
20 * Based on SpanNearQuery
21 * Todo: Make one Spanarray and switch between the results of A and B.
22 */
23
Nils Diewald5871e4d2014-11-07 03:48:25 +000024/**
Nils Diewaldbb33da22015-03-04 16:24:25 +000025 * SpanNextQuery matches two spans which are directly next to each
26 * other. It is
Eliza Margarethaf0171c52015-01-14 17:38:16 +000027 * identical to a phrase query with exactly two clauses.
28 *
Nils Diewaldbb33da22015-03-04 16:24:25 +000029 * In the example below, the SpanNextQuery retrieves {@link NextSpans}
30 * starting
31 * from the start position of {@link TermSpans} "turn" and ending at
32 * the end
Eliza Margarethaf0171c52015-01-14 17:38:16 +000033 * position of {@link TermSpans} "off" occurring immediately after the
34 * {@link TermSpans} "turn".
35 *
36 * <pre>
37 * SpanNextQuery sq = new SpanNextQuery(
Nils Diewaldbb33da22015-03-04 16:24:25 +000038 * new SpanTermQuery(new Term(&quot;tokens&quot;,&quot;s:turn&quot;)),
39 * new SpanTermQuery(new Term(&quot;tokens&quot;,
40 * &quot;s:off&quot;)));
Eliza Margarethaf0171c52015-01-14 17:38:16 +000041 * </pre>
42 *
Nils Diewald44d5fa12015-01-15 21:31:52 +000043 * @author diewald
44 * @author margaretha
Eliza Margarethaf0171c52015-01-14 17:38:16 +000045 *
Nils Diewaldf399a672013-11-18 17:55:22 +000046 */
Eliza Margarethaed3bb3b2014-01-14 10:53:56 +000047public class SpanNextQuery extends SimpleSpanQuery implements Cloneable {
Nils Diewaldf399a672013-11-18 17:55:22 +000048
Eliza Margarethaf0171c52015-01-14 17:38:16 +000049 /**
Nils Diewaldbb33da22015-03-04 16:24:25 +000050 * Constructs a SpanNextQuery for the two specified
51 * {@link SpanQuery
52 * SpanQueries} whose payloads are to be collected for the
53 * resulting {@link NextSpans}. The first SpanQuery is immediately
54 * followed by the
Eliza Margarethaf0171c52015-01-14 17:38:16 +000055 * second SpanQuery.
56 *
Nils Diewaldbb33da22015-03-04 16:24:25 +000057 * @param firstClause
58 * the first SpanQuery
59 * @param secondClause
60 * the second SpanQuery
Eliza Margarethaf0171c52015-01-14 17:38:16 +000061 */
Nils Diewaldbb33da22015-03-04 16:24:25 +000062 public SpanNextQuery (SpanQuery firstClause, SpanQuery secondClause) {
Eliza Margarethaf0171c52015-01-14 17:38:16 +000063 this(firstClause, secondClause, true);
Nils Diewaldf399a672013-11-18 17:55:22 +000064 };
65
Nils Diewaldbb33da22015-03-04 16:24:25 +000066
Eliza Margarethaf0171c52015-01-14 17:38:16 +000067 /**
Nils Diewaldbb33da22015-03-04 16:24:25 +000068 * Constructs a SpanNextQuery for the two specified
69 * {@link SpanQuery
70 * SpanQueries} where the first SpanQuery is immediately followed
71 * by the
Eliza Margarethaf0171c52015-01-14 17:38:16 +000072 * second SpanQuery.
73 *
Nils Diewaldbb33da22015-03-04 16:24:25 +000074 * @param firstClause
75 * the first SpanQuery
76 * @param secondClause
77 * the second SpanQuery
78 * @param collectPayloads
79 * a boolean flag representing the value
80 * <code>true</code> if payloads are to be collected,
81 * otherwise
82 * <code>false</code>.
Eliza Margarethaf0171c52015-01-14 17:38:16 +000083 */
Nils Diewaldbb33da22015-03-04 16:24:25 +000084 public SpanNextQuery (SpanQuery firstClause, SpanQuery secondClause,
85 boolean collectPayloads) {
Eliza Margarethaf0171c52015-01-14 17:38:16 +000086 super(firstClause, secondClause, collectPayloads);
Nils Diewaldf399a672013-11-18 17:55:22 +000087 };
88
Nils Diewaldbb33da22015-03-04 16:24:25 +000089
Nils Diewaldf399a672013-11-18 17:55:22 +000090 @Override
Akron700c1eb2015-09-25 16:57:30 +020091 // TODO: 5.3 removes getSpans fro SpanQuery ... oh, well ...
92 public Spans getSpans (final LeafReaderContext context, Bits acceptDocs,
Eliza Margarethaf0171c52015-01-14 17:38:16 +000093 Map<Term, TermContext> termContexts) throws IOException {
94 return (Spans) new NextSpans(this, context, acceptDocs, termContexts);
Nils Diewaldf399a672013-11-18 17:55:22 +000095 };
Nils Diewaldf399a672013-11-18 17:55:22 +000096
Nils Diewaldbb33da22015-03-04 16:24:25 +000097
Nils Diewaldf399a672013-11-18 17:55:22 +000098 @Override
Nils Diewaldbb33da22015-03-04 16:24:25 +000099 public SpanNextQuery clone () {
Eliza Margarethaf0171c52015-01-14 17:38:16 +0000100 SpanNextQuery spanNextQuery = new SpanNextQuery(
101 (SpanQuery) firstClause.clone(),
102 (SpanQuery) secondClause.clone(), collectPayloads);
103 spanNextQuery.setBoost(getBoost());
104 return spanNextQuery;
Nils Diewaldf399a672013-11-18 17:55:22 +0000105 };
Nils Diewald5871e4d2014-11-07 03:48:25 +0000106
Nils Diewaldbb33da22015-03-04 16:24:25 +0000107
Nils Diewald5871e4d2014-11-07 03:48:25 +0000108 /*
109 * Rewrite query in case it includes regular expressions or wildcards
110 */
111 @Override
Nils Diewaldbb33da22015-03-04 16:24:25 +0000112 public Query rewrite (IndexReader reader) throws IOException {
Eliza Margarethaf0171c52015-01-14 17:38:16 +0000113 SpanNextQuery clone = null;
Nils Diewald5871e4d2014-11-07 03:48:25 +0000114
Eliza Margarethaf0171c52015-01-14 17:38:16 +0000115 // Does the first clause needs a rewrite?
116 SpanQuery query = (SpanQuery) firstClause.rewrite(reader);
117 if (query != firstClause) {
118 if (clone == null)
119 clone = this.clone();
120 clone.firstClause = query;
Nils Diewaldbb33da22015-03-04 16:24:25 +0000121 };
Nils Diewald5871e4d2014-11-07 03:48:25 +0000122
Eliza Margarethaf0171c52015-01-14 17:38:16 +0000123 // Does the second clause needs a rewrite?
124 query = (SpanQuery) secondClause.rewrite(reader);
125 if (query != secondClause) {
126 if (clone == null)
127 clone = this.clone();
128 clone.secondClause = query;
Nils Diewaldbb33da22015-03-04 16:24:25 +0000129 };
Nils Diewald5871e4d2014-11-07 03:48:25 +0000130
Eliza Margarethaf0171c52015-01-14 17:38:16 +0000131 // There is a clone and it is important
132 if (clone != null)
133 return clone;
Nils Diewald5871e4d2014-11-07 03:48:25 +0000134
Eliza Margarethaf0171c52015-01-14 17:38:16 +0000135 return this;
Nils Diewald5871e4d2014-11-07 03:48:25 +0000136 };
137
Nils Diewaldbb33da22015-03-04 16:24:25 +0000138
Eliza Margaretha609fcc62014-02-13 14:10:20 +0000139 @Override
Nils Diewaldbb33da22015-03-04 16:24:25 +0000140 public String toString (String field) {
Eliza Margarethaf0171c52015-01-14 17:38:16 +0000141 StringBuilder sb = new StringBuilder();
142 sb.append("spanNext(");
143 sb.append(firstClause.toString(field));
144 sb.append(", ");
145 sb.append(secondClause.toString(field));
146 sb.append(")");
147 sb.append(ToStringUtils.boost(getBoost()));
148 return sb.toString();
Eliza Margaretha609fcc62014-02-13 14:10:20 +0000149 }
Nils Diewaldf399a672013-11-18 17:55:22 +0000150
Nils Diewaldbb33da22015-03-04 16:24:25 +0000151
Nils Diewaldf399a672013-11-18 17:55:22 +0000152 /** Returns true iff <code>o</code> is equal to this. */
153 @Override
Nils Diewaldbb33da22015-03-04 16:24:25 +0000154 public boolean equals (Object o) {
Eliza Margarethaf0171c52015-01-14 17:38:16 +0000155 if (this == o)
156 return true;
157 if (!(o instanceof SpanNextQuery))
158 return false;
Nils Diewaldf399a672013-11-18 17:55:22 +0000159
Eliza Margarethaf0171c52015-01-14 17:38:16 +0000160 final SpanNextQuery spanNextQuery = (SpanNextQuery) o;
161
162 if (collectPayloads != spanNextQuery.collectPayloads)
163 return false;
164 if (!firstClause.equals(spanNextQuery.firstClause))
165 return false;
166 if (!secondClause.equals(spanNextQuery.secondClause))
167 return false;
168
169 return getBoost() == spanNextQuery.getBoost();
Nils Diewaldf399a672013-11-18 17:55:22 +0000170 };
171
Nils Diewaldbb33da22015-03-04 16:24:25 +0000172
Nils Diewaldf399a672013-11-18 17:55:22 +0000173 // I don't know what I am doing here
174 @Override
Nils Diewaldbb33da22015-03-04 16:24:25 +0000175 public int hashCode () {
Eliza Margarethaf0171c52015-01-14 17:38:16 +0000176 int result;
177 result = firstClause.hashCode() + secondClause.hashCode();
178 result ^= (result << 31) | (result >>> 2); // reversible
179 result += Float.floatToRawIntBits(getBoost());
180 return result;
Nils Diewaldf399a672013-11-18 17:55:22 +0000181 };
182};