| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.lucene.search.spans; |
| |
| |
| import org.apache.lucene.index.Term; |
| import org.apache.lucene.search.BooleanClause.Occur; |
| import org.apache.lucene.search.BooleanQuery; |
| import org.apache.lucene.search.PhraseQuery; |
| import org.apache.lucene.search.Query; |
| import org.apache.lucene.search.SearchEquivalenceTestBase; |
| import org.apache.lucene.search.TermQuery; |
| |
| import static org.apache.lucene.search.spans.SpanTestUtil.*; |
| |
| /** |
| * Basic equivalence tests for span queries |
| */ |
| public class TestSpanSearchEquivalence extends SearchEquivalenceTestBase { |
| |
| // TODO: we could go a little crazy for a lot of these, |
| // but these are just simple minimal cases in case something |
| // goes horribly wrong. Put more intense tests elsewhere. |
| |
| /** SpanTermQuery(A) = TermQuery(A) */ |
| public void testSpanTermVersusTerm() throws Exception { |
| Term t1 = randomTerm(); |
| assertSameScores(new TermQuery(t1), spanQuery(new SpanTermQuery(t1))); |
| } |
| |
| /** SpanOrQuery(A) = SpanTermQuery(A) */ |
| public void testSpanOrVersusTerm() throws Exception { |
| Term t1 = randomTerm(); |
| SpanQuery term = spanQuery(new SpanTermQuery(t1)); |
| assertSameSet(spanQuery(new SpanOrQuery(term)), term); |
| } |
| |
| /** SpanOrQuery(A, A) = SpanTermQuery(A) */ |
| public void testSpanOrDoubleVersusTerm() throws Exception { |
| Term t1 = randomTerm(); |
| SpanQuery term = spanQuery(new SpanTermQuery(t1)); |
| assertSameSet(spanQuery(new SpanOrQuery(term, term)), term); |
| } |
| |
| /** SpanOrQuery(A, B) = (A B) */ |
| public void testSpanOrVersusBooleanTerm() throws Exception { |
| Term t1 = randomTerm(); |
| Term t2 = randomTerm(); |
| BooleanQuery.Builder q1 = new BooleanQuery.Builder(); |
| q1.add(new TermQuery(t1), Occur.SHOULD); |
| q1.add(new TermQuery(t2), Occur.SHOULD); |
| SpanQuery q2 = spanQuery(new SpanOrQuery(spanQuery(new SpanTermQuery(t1)), spanQuery(new SpanTermQuery(t2)))); |
| assertSameSet(q1.build(), q2); |
| } |
| |
| /** SpanOrQuery(SpanNearQuery[A B], SpanNearQuery[C D]) = (SpanNearQuery[A B], SpanNearQuery[C D]) */ |
| public void testSpanOrVersusBooleanNear() throws Exception { |
| Term t1 = randomTerm(); |
| Term t2 = randomTerm(); |
| Term t3 = randomTerm(); |
| Term t4 = randomTerm(); |
| SpanQuery near1 = spanQuery(new SpanNearQuery(new SpanQuery[] { |
| spanQuery(new SpanTermQuery(t1)), |
| spanQuery(new SpanTermQuery(t2)) |
| }, 10, random().nextBoolean())); |
| SpanQuery near2 = spanQuery(new SpanNearQuery(new SpanQuery[] { |
| spanQuery(new SpanTermQuery(t3)), |
| spanQuery(new SpanTermQuery(t4)) |
| }, 10, random().nextBoolean())); |
| BooleanQuery.Builder q1 = new BooleanQuery.Builder(); |
| q1.add(near1, Occur.SHOULD); |
| q1.add(near2, Occur.SHOULD); |
| SpanQuery q2 = spanQuery(new SpanOrQuery(near1, near2)); |
| assertSameSet(q1.build(), q2); |
| } |
| |
| /** SpanNotQuery(A, B) ⊆ SpanTermQuery(A) */ |
| public void testSpanNotVersusSpanTerm() throws Exception { |
| Term t1 = randomTerm(); |
| Term t2 = randomTerm(); |
| assertSubsetOf(spanQuery(new SpanNotQuery(spanQuery(new SpanTermQuery(t1)), spanQuery(new SpanTermQuery(t2)))), |
| spanQuery(new SpanTermQuery(t1))); |
| } |
| |
| /** SpanNotQuery(A, [B C]) ⊆ SpanTermQuery(A) */ |
| public void testSpanNotNearVersusSpanTerm() throws Exception { |
| Term t1 = randomTerm(); |
| Term t2 = randomTerm(); |
| Term t3 = randomTerm(); |
| SpanQuery near = spanQuery(new SpanNearQuery(new SpanQuery[] { |
| spanQuery(new SpanTermQuery(t2)), |
| spanQuery(new SpanTermQuery(t3)) |
| }, 10, random().nextBoolean())); |
| assertSubsetOf(spanQuery(new SpanNotQuery(spanQuery(new SpanTermQuery(t1)), near)), spanQuery(new SpanTermQuery(t1))); |
| } |
| |
| /** SpanNotQuery([A B], C) ⊆ SpanNearQuery([A B]) */ |
| public void testSpanNotVersusSpanNear() throws Exception { |
| Term t1 = randomTerm(); |
| Term t2 = randomTerm(); |
| Term t3 = randomTerm(); |
| SpanQuery near = spanQuery(new SpanNearQuery(new SpanQuery[] { |
| spanQuery(new SpanTermQuery(t1)), |
| spanQuery(new SpanTermQuery(t2)) |
| }, 10, random().nextBoolean())); |
| assertSubsetOf(spanQuery(new SpanNotQuery(near, spanQuery(new SpanTermQuery(t3)))), near); |
| } |
| |
| /** SpanNotQuery([A B], [C D]) ⊆ SpanNearQuery([A B]) */ |
| public void testSpanNotNearVersusSpanNear() throws Exception { |
| Term t1 = randomTerm(); |
| Term t2 = randomTerm(); |
| Term t3 = randomTerm(); |
| Term t4 = randomTerm(); |
| SpanQuery near1 = spanQuery(new SpanNearQuery(new SpanQuery[] { |
| spanQuery(new SpanTermQuery(t1)), |
| spanQuery(new SpanTermQuery(t2)) |
| }, 10, random().nextBoolean())); |
| SpanQuery near2 = spanQuery(new SpanNearQuery(new SpanQuery[] { |
| spanQuery(new SpanTermQuery(t3)), |
| spanQuery(new SpanTermQuery(t4)) |
| }, 10, random().nextBoolean())); |
| assertSubsetOf(spanQuery(new SpanNotQuery(near1, near2)), near1); |
| } |
| |
| /** SpanFirstQuery(A, 10) ⊆ SpanTermQuery(A) */ |
| public void testSpanFirstVersusSpanTerm() throws Exception { |
| Term t1 = randomTerm(); |
| assertSubsetOf(spanQuery(new SpanFirstQuery(spanQuery(new SpanTermQuery(t1)), 10)), |
| spanQuery(new SpanTermQuery(t1))); |
| } |
| |
| /** SpanNearQuery([A, B], 0, true) = "A B" */ |
| public void testSpanNearVersusPhrase() throws Exception { |
| Term t1 = randomTerm(); |
| Term t2 = randomTerm(); |
| SpanQuery subquery[] = new SpanQuery[] { |
| spanQuery(new SpanTermQuery(t1)), |
| spanQuery(new SpanTermQuery(t2)) |
| }; |
| SpanQuery q1 = spanQuery(new SpanNearQuery(subquery, 0, true)); |
| PhraseQuery q2 = new PhraseQuery(t1.field(), t1.bytes(), t2.bytes()); |
| if (t1.equals(t2)) { |
| assertSameSet(q1, q2); |
| } else { |
| assertSameScores(q1, q2); |
| } |
| } |
| |
| /** SpanNearQuery([A, B], ∞, false) = +A +B */ |
| public void testSpanNearVersusBooleanAnd() throws Exception { |
| Term t1 = randomTerm(); |
| Term t2 = randomTerm(); |
| SpanQuery subquery[] = new SpanQuery[] { |
| spanQuery(new SpanTermQuery(t1)), |
| spanQuery(new SpanTermQuery(t2)) |
| }; |
| SpanQuery q1 = spanQuery(new SpanNearQuery(subquery, Integer.MAX_VALUE, false)); |
| BooleanQuery.Builder q2 = new BooleanQuery.Builder(); |
| q2.add(new TermQuery(t1), Occur.MUST); |
| q2.add(new TermQuery(t2), Occur.MUST); |
| assertSameSet(q1, q2.build()); |
| } |
| |
| /** SpanNearQuery([A B], 0, false) ⊆ SpanNearQuery([A B], 1, false) */ |
| public void testSpanNearVersusSloppySpanNear() throws Exception { |
| Term t1 = randomTerm(); |
| Term t2 = randomTerm(); |
| SpanQuery subquery[] = new SpanQuery[] { |
| spanQuery(new SpanTermQuery(t1)), |
| spanQuery(new SpanTermQuery(t2)) |
| }; |
| SpanQuery q1 = spanQuery(new SpanNearQuery(subquery, 0, false)); |
| SpanQuery q2 = spanQuery(new SpanNearQuery(subquery, 1, false)); |
| assertSubsetOf(q1, q2); |
| } |
| |
| /** SpanNearQuery([A B], 3, true) ⊆ SpanNearQuery([A B], 3, false) */ |
| public void testSpanNearInOrderVersusOutOfOrder() throws Exception { |
| Term t1 = randomTerm(); |
| Term t2 = randomTerm(); |
| SpanQuery subquery[] = new SpanQuery[] { |
| spanQuery(new SpanTermQuery(t1)), |
| spanQuery(new SpanTermQuery(t2)) |
| }; |
| SpanQuery q1 = spanQuery(new SpanNearQuery(subquery, 3, true)); |
| SpanQuery q2 = spanQuery(new SpanNearQuery(subquery, 3, false)); |
| assertSubsetOf(q1, q2); |
| } |
| |
| /** SpanNearQuery([A B], N, false) ⊆ SpanNearQuery([A B], N+1, false) */ |
| public void testSpanNearIncreasingSloppiness() throws Exception { |
| Term t1 = randomTerm(); |
| Term t2 = randomTerm(); |
| SpanQuery subquery[] = new SpanQuery[] { |
| spanQuery(new SpanTermQuery(t1)), |
| spanQuery(new SpanTermQuery(t2)) |
| }; |
| for (int i = 0; i < 10; i++) { |
| SpanQuery q1 = spanQuery(new SpanNearQuery(subquery, i, false)); |
| SpanQuery q2 = spanQuery(new SpanNearQuery(subquery, i+1, false)); |
| assertSubsetOf(q1, q2); |
| } |
| } |
| |
| /** SpanNearQuery([A B C], N, false) ⊆ SpanNearQuery([A B C], N+1, false) */ |
| public void testSpanNearIncreasingSloppiness3() throws Exception { |
| Term t1 = randomTerm(); |
| Term t2 = randomTerm(); |
| Term t3 = randomTerm(); |
| SpanQuery subquery[] = new SpanQuery[] { |
| spanQuery(new SpanTermQuery(t1)), |
| spanQuery(new SpanTermQuery(t2)), |
| spanQuery(new SpanTermQuery(t3)) |
| }; |
| for (int i = 0; i < 10; i++) { |
| SpanQuery q1 = spanQuery(new SpanNearQuery(subquery, i, false)); |
| SpanQuery q2 = spanQuery(new SpanNearQuery(subquery, i+1, false)); |
| assertSubsetOf(q1, q2); |
| } |
| } |
| |
| /** SpanNearQuery([A B], N, true) ⊆ SpanNearQuery([A B], N+1, true) */ |
| public void testSpanNearIncreasingOrderedSloppiness() throws Exception { |
| Term t1 = randomTerm(); |
| Term t2 = randomTerm(); |
| SpanQuery subquery[] = new SpanQuery[] { |
| spanQuery(new SpanTermQuery(t1)), |
| spanQuery(new SpanTermQuery(t2)) |
| }; |
| for (int i = 0; i < 10; i++) { |
| SpanQuery q1 = spanQuery(new SpanNearQuery(subquery, i, false)); |
| SpanQuery q2 = spanQuery(new SpanNearQuery(subquery, i+1, false)); |
| assertSubsetOf(q1, q2); |
| } |
| } |
| |
| /** SpanNearQuery([A B C], N, true) ⊆ SpanNearQuery([A B C], N+1, true) */ |
| public void testSpanNearIncreasingOrderedSloppiness3() throws Exception { |
| Term t1 = randomTerm(); |
| Term t2 = randomTerm(); |
| Term t3 = randomTerm(); |
| SpanQuery subquery[] = new SpanQuery[] { |
| spanQuery(new SpanTermQuery(t1)), |
| spanQuery(new SpanTermQuery(t2)), |
| spanQuery(new SpanTermQuery(t3)) |
| }; |
| for (int i = 0; i < 10; i++) { |
| SpanQuery q1 = spanQuery(new SpanNearQuery(subquery, i, true)); |
| SpanQuery q2 = spanQuery(new SpanNearQuery(subquery, i+1, true)); |
| assertSubsetOf(q1, q2); |
| } |
| } |
| |
| /** SpanPositionRangeQuery(A, M, N) ⊆ TermQuery(A) */ |
| public void testSpanRangeTerm() throws Exception { |
| Term t1 = randomTerm(); |
| for (int i = 0; i < 5; i++) { |
| for (int j = 0; j < 5; j++) { |
| Query q1 = spanQuery(new SpanPositionRangeQuery(spanQuery(new SpanTermQuery(t1)), i, i+j)); |
| Query q2 = new TermQuery(t1); |
| assertSubsetOf(q1, q2); |
| } |
| } |
| } |
| |
| /** SpanPositionRangeQuery(A, M, N) ⊆ SpanFirstQuery(A, M, N+1) */ |
| public void testSpanRangeTermIncreasingEnd() throws Exception { |
| Term t1 = randomTerm(); |
| for (int i = 0; i < 5; i++) { |
| for (int j = 0; j < 5; j++) { |
| Query q1 = spanQuery(new SpanPositionRangeQuery(spanQuery(new SpanTermQuery(t1)), i, i+j)); |
| Query q2 = spanQuery(new SpanPositionRangeQuery(spanQuery(new SpanTermQuery(t1)), i, i+j+1)); |
| assertSubsetOf(q1, q2); |
| } |
| } |
| } |
| |
| /** SpanPositionRangeQuery(A, 0, ∞) = TermQuery(A) */ |
| public void testSpanRangeTermEverything() throws Exception { |
| Term t1 = randomTerm(); |
| Query q1 = spanQuery(new SpanPositionRangeQuery(spanQuery(new SpanTermQuery(t1)), 0, Integer.MAX_VALUE)); |
| Query q2 = new TermQuery(t1); |
| assertSameSet(q1, q2); |
| } |
| |
| /** SpanPositionRangeQuery([A B], M, N) ⊆ SpanNearQuery([A B]) */ |
| public void testSpanRangeNear() throws Exception { |
| Term t1 = randomTerm(); |
| Term t2 = randomTerm(); |
| SpanQuery subquery[] = new SpanQuery[] { |
| spanQuery(new SpanTermQuery(t1)), |
| spanQuery(new SpanTermQuery(t2)) |
| }; |
| SpanQuery nearQuery = spanQuery(new SpanNearQuery(subquery, 10, true)); |
| for (int i = 0; i < 5; i++) { |
| for (int j = 0; j < 5; j++) { |
| Query q1 = spanQuery(new SpanPositionRangeQuery(nearQuery, i, i+j)); |
| Query q2 = nearQuery; |
| assertSubsetOf(q1, q2); |
| } |
| } |
| } |
| |
| /** SpanPositionRangeQuery([A B], M, N) ⊆ SpanFirstQuery([A B], M, N+1) */ |
| public void testSpanRangeNearIncreasingEnd() throws Exception { |
| Term t1 = randomTerm(); |
| Term t2 = randomTerm(); |
| SpanQuery subquery[] = new SpanQuery[] { |
| spanQuery(new SpanTermQuery(t1)), |
| spanQuery(new SpanTermQuery(t2)) |
| }; |
| SpanQuery nearQuery = spanQuery(new SpanNearQuery(subquery, 10, true)); |
| for (int i = 0; i < 5; i++) { |
| for (int j = 0; j < 5; j++) { |
| Query q1 = spanQuery(new SpanPositionRangeQuery(nearQuery, i, i+j)); |
| Query q2 = spanQuery(new SpanPositionRangeQuery(nearQuery, i, i+j+1)); |
| assertSubsetOf(q1, q2); |
| } |
| } |
| } |
| |
| /** SpanPositionRangeQuery([A B], ∞) = SpanNearQuery([A B]) */ |
| public void testSpanRangeNearEverything() throws Exception { |
| Term t1 = randomTerm(); |
| Term t2 = randomTerm(); |
| SpanQuery subquery[] = new SpanQuery[] { |
| spanQuery(new SpanTermQuery(t1)), |
| spanQuery(new SpanTermQuery(t2)) |
| }; |
| SpanQuery nearQuery = spanQuery(new SpanNearQuery(subquery, 10, true)); |
| Query q1 = spanQuery(new SpanPositionRangeQuery(nearQuery, 0, Integer.MAX_VALUE)); |
| Query q2 = nearQuery; |
| assertSameSet(q1, q2); |
| } |
| |
| /** SpanFirstQuery(A, N) ⊆ TermQuery(A) */ |
| public void testSpanFirstTerm() throws Exception { |
| Term t1 = randomTerm(); |
| for (int i = 0; i < 10; i++) { |
| Query q1 = spanQuery(new SpanFirstQuery(spanQuery(new SpanTermQuery(t1)), i)); |
| Query q2 = new TermQuery(t1); |
| assertSubsetOf(q1, q2); |
| } |
| } |
| |
| /** SpanFirstQuery(A, N) ⊆ SpanFirstQuery(A, N+1) */ |
| public void testSpanFirstTermIncreasing() throws Exception { |
| Term t1 = randomTerm(); |
| for (int i = 0; i < 10; i++) { |
| Query q1 = spanQuery(new SpanFirstQuery(spanQuery(new SpanTermQuery(t1)), i)); |
| Query q2 = spanQuery(new SpanFirstQuery(spanQuery(new SpanTermQuery(t1)), i+1)); |
| assertSubsetOf(q1, q2); |
| } |
| } |
| |
| /** SpanFirstQuery(A, ∞) = TermQuery(A) */ |
| public void testSpanFirstTermEverything() throws Exception { |
| Term t1 = randomTerm(); |
| Query q1 = spanQuery(new SpanFirstQuery(spanQuery(new SpanTermQuery(t1)), Integer.MAX_VALUE)); |
| Query q2 = new TermQuery(t1); |
| assertSameSet(q1, q2); |
| } |
| |
| /** SpanFirstQuery([A B], N) ⊆ SpanNearQuery([A B]) */ |
| public void testSpanFirstNear() throws Exception { |
| Term t1 = randomTerm(); |
| Term t2 = randomTerm(); |
| SpanQuery subquery[] = new SpanQuery[] { |
| spanQuery(new SpanTermQuery(t1)), |
| spanQuery(new SpanTermQuery(t2)) |
| }; |
| SpanQuery nearQuery = spanQuery(new SpanNearQuery(subquery, 10, true)); |
| for (int i = 0; i < 10; i++) { |
| Query q1 = spanQuery(new SpanFirstQuery(nearQuery, i)); |
| Query q2 = nearQuery; |
| assertSubsetOf(q1, q2); |
| } |
| } |
| |
| /** SpanFirstQuery([A B], N) ⊆ SpanFirstQuery([A B], N+1) */ |
| public void testSpanFirstNearIncreasing() throws Exception { |
| Term t1 = randomTerm(); |
| Term t2 = randomTerm(); |
| SpanQuery subquery[] = new SpanQuery[] { |
| spanQuery(new SpanTermQuery(t1)), |
| spanQuery(new SpanTermQuery(t2)) |
| }; |
| SpanQuery nearQuery = spanQuery(new SpanNearQuery(subquery, 10, true)); |
| for (int i = 0; i < 10; i++) { |
| Query q1 = spanQuery(new SpanFirstQuery(nearQuery, i)); |
| Query q2 = spanQuery(new SpanFirstQuery(nearQuery, i+1)); |
| assertSubsetOf(q1, q2); |
| } |
| } |
| |
| /** SpanFirstQuery([A B], ∞) = SpanNearQuery([A B]) */ |
| public void testSpanFirstNearEverything() throws Exception { |
| Term t1 = randomTerm(); |
| Term t2 = randomTerm(); |
| SpanQuery subquery[] = new SpanQuery[] { |
| spanQuery(new SpanTermQuery(t1)), |
| spanQuery(new SpanTermQuery(t2)) |
| }; |
| SpanQuery nearQuery = spanQuery(new SpanNearQuery(subquery, 10, true)); |
| Query q1 = spanQuery(new SpanFirstQuery(nearQuery, Integer.MAX_VALUE)); |
| Query q2 = nearQuery; |
| assertSameSet(q1, q2); |
| } |
| |
| /** SpanWithinQuery(A, B) ⊆ SpanNearQuery(A) */ |
| public void testSpanWithinVsNear() throws Exception { |
| Term t1 = randomTerm(); |
| Term t2 = randomTerm(); |
| SpanQuery subquery[] = new SpanQuery[] { |
| spanQuery(new SpanTermQuery(t1)), |
| spanQuery(new SpanTermQuery(t2)) |
| }; |
| SpanQuery nearQuery = spanQuery(new SpanNearQuery(subquery, 10, true)); |
| |
| Term t3 = randomTerm(); |
| SpanQuery termQuery = spanQuery(new SpanTermQuery(t3)); |
| Query q1 = spanQuery(new SpanWithinQuery(nearQuery, termQuery)); |
| assertSubsetOf(q1, termQuery); |
| } |
| |
| /** SpanWithinQuery(A, B) = SpanContainingQuery(A, B) */ |
| public void testSpanWithinVsContaining() throws Exception { |
| Term t1 = randomTerm(); |
| Term t2 = randomTerm(); |
| SpanQuery subquery[] = new SpanQuery[] { |
| spanQuery(new SpanTermQuery(t1)), |
| spanQuery(new SpanTermQuery(t2)) |
| }; |
| SpanQuery nearQuery = spanQuery(new SpanNearQuery(subquery, 10, true)); |
| |
| Term t3 = randomTerm(); |
| SpanQuery termQuery = spanQuery(new SpanTermQuery(t3)); |
| Query q1 = spanQuery(new SpanWithinQuery(nearQuery, termQuery)); |
| Query q2 = spanQuery(new SpanContainingQuery(nearQuery, termQuery)); |
| assertSameSet(q1, q2); |
| } |
| |
| public void testSpanBoostQuerySimplification() throws Exception { |
| float b1 = random().nextFloat() * 10; |
| float b2 = random().nextFloat() * 10; |
| Term term = randomTerm(); |
| |
| Query q1 = new SpanBoostQuery(new SpanBoostQuery(new SpanTermQuery(term), b2), b1); |
| // Use AssertingQuery to prevent BoostQuery from merging inner and outer boosts |
| Query q2 = new SpanBoostQuery(new AssertingSpanQuery(new SpanBoostQuery(new SpanTermQuery(term), b2)), b1); |
| |
| assertSameScores(q1, q2); |
| } |
| } |