| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 1 | package de.ids_mannheim.korap.query; |
| 2 | |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 3 | import java.io.IOException; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 4 | import java.util.Map; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 5 | |
| Akron | 700c1eb | 2015-09-25 16:57:30 +0200 | [diff] [blame] | 6 | import org.apache.lucene.index.LeafReaderContext; |
| Nils Diewald | 5871e4d | 2014-11-07 03:48:25 +0000 | [diff] [blame] | 7 | import org.apache.lucene.index.IndexReader; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 8 | import org.apache.lucene.index.Term; |
| 9 | import org.apache.lucene.index.TermContext; |
| Eliza Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 10 | import org.apache.lucene.search.Query; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 11 | import org.apache.lucene.search.spans.SpanQuery; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 12 | import org.apache.lucene.search.spans.Spans; |
| Eliza Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 13 | import org.apache.lucene.search.spans.TermSpans; |
| Eliza Margaretha | 83b9537 | 2014-01-23 09:18:07 +0000 | [diff] [blame] | 14 | import org.apache.lucene.util.Bits; |
| Eliza Margaretha | 609fcc6 | 2014-02-13 14:10:20 +0000 | [diff] [blame] | 15 | import org.apache.lucene.util.ToStringUtils; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 16 | |
| 17 | import de.ids_mannheim.korap.query.spans.NextSpans; |
| 18 | |
| Nils Diewald | 44d5fa1 | 2015-01-15 21:31:52 +0000 | [diff] [blame] | 19 | /* |
| 20 | * Based on SpanNearQuery |
| 21 | * Todo: Make one Spanarray and switch between the results of A and B. |
| 22 | */ |
| 23 | |
| Nils Diewald | 5871e4d | 2014-11-07 03:48:25 +0000 | [diff] [blame] | 24 | /** |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 25 | * SpanNextQuery matches two spans which are directly next to each |
| 26 | * other. It is |
| Eliza Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 27 | * identical to a phrase query with exactly two clauses. |
| 28 | * |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 29 | * 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 Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 33 | * position of {@link TermSpans} "off" occurring immediately after the |
| 34 | * {@link TermSpans} "turn". |
| 35 | * |
| 36 | * <pre> |
| 37 | * SpanNextQuery sq = new SpanNextQuery( |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 38 | * new SpanTermQuery(new Term("tokens","s:turn")), |
| 39 | * new SpanTermQuery(new Term("tokens", |
| 40 | * "s:off"))); |
| Eliza Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 41 | * </pre> |
| 42 | * |
| Nils Diewald | 44d5fa1 | 2015-01-15 21:31:52 +0000 | [diff] [blame] | 43 | * @author diewald |
| 44 | * @author margaretha |
| Eliza Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 45 | * |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 46 | */ |
| Eliza Margaretha | ed3bb3b | 2014-01-14 10:53:56 +0000 | [diff] [blame] | 47 | public class SpanNextQuery extends SimpleSpanQuery implements Cloneable { |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 48 | |
| Eliza Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 49 | /** |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 50 | * 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 Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 55 | * second SpanQuery. |
| 56 | * |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 57 | * @param firstClause |
| 58 | * the first SpanQuery |
| 59 | * @param secondClause |
| 60 | * the second SpanQuery |
| Eliza Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 61 | */ |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 62 | public SpanNextQuery (SpanQuery firstClause, SpanQuery secondClause) { |
| Eliza Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 63 | this(firstClause, secondClause, true); |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 64 | }; |
| 65 | |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 66 | |
| Eliza Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 67 | /** |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 68 | * Constructs a SpanNextQuery for the two specified |
| 69 | * {@link SpanQuery |
| 70 | * SpanQueries} where the first SpanQuery is immediately followed |
| 71 | * by the |
| Eliza Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 72 | * second SpanQuery. |
| 73 | * |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 74 | * @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 Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 83 | */ |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 84 | public SpanNextQuery (SpanQuery firstClause, SpanQuery secondClause, |
| 85 | boolean collectPayloads) { |
| Eliza Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 86 | super(firstClause, secondClause, collectPayloads); |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 87 | }; |
| 88 | |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 89 | |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 90 | @Override |
| Akron | 700c1eb | 2015-09-25 16:57:30 +0200 | [diff] [blame] | 91 | // TODO: 5.3 removes getSpans fro SpanQuery ... oh, well ... |
| 92 | public Spans getSpans (final LeafReaderContext context, Bits acceptDocs, |
| Eliza Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 93 | Map<Term, TermContext> termContexts) throws IOException { |
| 94 | return (Spans) new NextSpans(this, context, acceptDocs, termContexts); |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 95 | }; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 96 | |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 97 | |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 98 | @Override |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 99 | public SpanNextQuery clone () { |
| Eliza Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 100 | SpanNextQuery spanNextQuery = new SpanNextQuery( |
| 101 | (SpanQuery) firstClause.clone(), |
| 102 | (SpanQuery) secondClause.clone(), collectPayloads); |
| 103 | spanNextQuery.setBoost(getBoost()); |
| 104 | return spanNextQuery; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 105 | }; |
| Nils Diewald | 5871e4d | 2014-11-07 03:48:25 +0000 | [diff] [blame] | 106 | |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 107 | |
| Nils Diewald | 5871e4d | 2014-11-07 03:48:25 +0000 | [diff] [blame] | 108 | /* |
| 109 | * Rewrite query in case it includes regular expressions or wildcards |
| 110 | */ |
| 111 | @Override |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 112 | public Query rewrite (IndexReader reader) throws IOException { |
| Eliza Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 113 | SpanNextQuery clone = null; |
| Nils Diewald | 5871e4d | 2014-11-07 03:48:25 +0000 | [diff] [blame] | 114 | |
| Eliza Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 115 | // 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 Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 121 | }; |
| Nils Diewald | 5871e4d | 2014-11-07 03:48:25 +0000 | [diff] [blame] | 122 | |
| Eliza Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 123 | // 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 Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 129 | }; |
| Nils Diewald | 5871e4d | 2014-11-07 03:48:25 +0000 | [diff] [blame] | 130 | |
| Eliza Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 131 | // There is a clone and it is important |
| 132 | if (clone != null) |
| 133 | return clone; |
| Nils Diewald | 5871e4d | 2014-11-07 03:48:25 +0000 | [diff] [blame] | 134 | |
| Eliza Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 135 | return this; |
| Nils Diewald | 5871e4d | 2014-11-07 03:48:25 +0000 | [diff] [blame] | 136 | }; |
| 137 | |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 138 | |
| Eliza Margaretha | 609fcc6 | 2014-02-13 14:10:20 +0000 | [diff] [blame] | 139 | @Override |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 140 | public String toString (String field) { |
| Eliza Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 141 | 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 Margaretha | 609fcc6 | 2014-02-13 14:10:20 +0000 | [diff] [blame] | 149 | } |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 150 | |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 151 | |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 152 | /** Returns true iff <code>o</code> is equal to this. */ |
| 153 | @Override |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 154 | public boolean equals (Object o) { |
| Eliza Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 155 | if (this == o) |
| 156 | return true; |
| 157 | if (!(o instanceof SpanNextQuery)) |
| 158 | return false; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 159 | |
| Eliza Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 160 | 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 Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 170 | }; |
| 171 | |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 172 | |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 173 | // I don't know what I am doing here |
| 174 | @Override |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 175 | public int hashCode () { |
| Eliza Margaretha | f0171c5 | 2015-01-14 17:38:16 +0000 | [diff] [blame] | 176 | int result; |
| 177 | result = firstClause.hashCode() + secondClause.hashCode(); |
| 178 | result ^= (result << 31) | (result >>> 2); // reversible |
| 179 | result += Float.floatToRawIntBits(getBoost()); |
| 180 | return result; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 181 | }; |
| 182 | }; |