001: package org.apache.lucene.search;
002:
003: /**
004: * Licensed to the Apache Software Foundation (ASF) under one or more
005: * contributor license agreements. See the NOTICE file distributed with
006: * this work for additional information regarding copyright ownership.
007: * The ASF licenses this file to You under the Apache License, Version 2.0
008: * (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS,
015: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016: * See the License for the specific language governing permissions and
017: * limitations under the License.
018: */
019:
020: import org.apache.lucene.search.BooleanClause.Occur;
021: import org.apache.lucene.search.spans.*;
022:
023: /**
024: * TestExplanations subclass that builds up super crazy complex queries
025: * on the assumption that if the explanations work out right for them,
026: * they should work for anything.
027: */
028: public class TestComplexExplanations extends TestExplanations {
029:
030: /**
031: * Override the Similarity used in our searcher with one that plays
032: * nice with boosts of 0.0
033: */
034: public void setUp() throws Exception {
035: super .setUp();
036: searcher.setSimilarity(createQnorm1Similarity());
037: }
038:
039: // must be static for weight serialization tests
040: private static DefaultSimilarity createQnorm1Similarity() {
041: return new DefaultSimilarity() {
042: public float queryNorm(float sumOfSquaredWeights) {
043: return 1.0f; // / (float) Math.sqrt(1.0f + sumOfSquaredWeights);
044: }
045: };
046: }
047:
048: public void test1() throws Exception {
049:
050: BooleanQuery q = new BooleanQuery();
051:
052: q.add(qp.parse("\"w1 w2\"~1"), Occur.MUST);
053: q.add(snear(st("w2"), sor("w5", "zz"), 4, true), Occur.SHOULD);
054: q.add(snear(sf("w3", 2), st("w2"), st("w3"), 5, true),
055: Occur.SHOULD);
056:
057: Query t = new FilteredQuery(qp.parse("xx"), new ItemizedFilter(
058: new int[] { 1, 3 }));
059: t.setBoost(1000);
060: q.add(t, Occur.SHOULD);
061:
062: t = new ConstantScoreQuery(new ItemizedFilter(
063: new int[] { 0, 2 }));
064: t.setBoost(30);
065: q.add(t, Occur.SHOULD);
066:
067: DisjunctionMaxQuery dm = new DisjunctionMaxQuery(0.2f);
068: dm.add(snear(st("w2"), sor("w5", "zz"), 4, true));
069: dm.add(qp.parse("QQ"));
070: dm.add(qp.parse("xx yy -zz"));
071: dm.add(qp.parse("-xx -w1"));
072:
073: DisjunctionMaxQuery dm2 = new DisjunctionMaxQuery(0.5f);
074: dm2.add(qp.parse("w1"));
075: dm2.add(qp.parse("w2"));
076: dm2.add(qp.parse("w3"));
077: dm.add(dm2);
078:
079: q.add(dm, Occur.SHOULD);
080:
081: BooleanQuery b = new BooleanQuery();
082: b.setMinimumNumberShouldMatch(2);
083: b.add(snear("w1", "w2", 1, true), Occur.SHOULD);
084: b.add(snear("w2", "w3", 1, true), Occur.SHOULD);
085: b.add(snear("w1", "w3", 3, true), Occur.SHOULD);
086:
087: q.add(b, Occur.SHOULD);
088:
089: qtest(q, new int[] { 0, 1, 2 });
090: }
091:
092: public void test2() throws Exception {
093:
094: BooleanQuery q = new BooleanQuery();
095:
096: q.add(qp.parse("\"w1 w2\"~1"), Occur.MUST);
097: q.add(snear(st("w2"), sor("w5", "zz"), 4, true), Occur.SHOULD);
098: q.add(snear(sf("w3", 2), st("w2"), st("w3"), 5, true),
099: Occur.SHOULD);
100:
101: Query t = new FilteredQuery(qp.parse("xx"), new ItemizedFilter(
102: new int[] { 1, 3 }));
103: t.setBoost(1000);
104: q.add(t, Occur.SHOULD);
105:
106: t = new ConstantScoreQuery(new ItemizedFilter(
107: new int[] { 0, 2 }));
108: t.setBoost(-20.0f);
109: q.add(t, Occur.SHOULD);
110:
111: DisjunctionMaxQuery dm = new DisjunctionMaxQuery(0.2f);
112: dm.add(snear(st("w2"), sor("w5", "zz"), 4, true));
113: dm.add(qp.parse("QQ"));
114: dm.add(qp.parse("xx yy -zz"));
115: dm.add(qp.parse("-xx -w1"));
116:
117: DisjunctionMaxQuery dm2 = new DisjunctionMaxQuery(0.5f);
118: dm2.add(qp.parse("w1"));
119: dm2.add(qp.parse("w2"));
120: dm2.add(qp.parse("w3"));
121: dm.add(dm2);
122:
123: q.add(dm, Occur.SHOULD);
124:
125: BooleanQuery b = new BooleanQuery();
126: b.setMinimumNumberShouldMatch(2);
127: b.add(snear("w1", "w2", 1, true), Occur.SHOULD);
128: b.add(snear("w2", "w3", 1, true), Occur.SHOULD);
129: b.add(snear("w1", "w3", 3, true), Occur.SHOULD);
130: b.setBoost(0.0f);
131:
132: q.add(b, Occur.SHOULD);
133:
134: qtest(q, new int[] { 0, 1, 2 });
135: }
136:
137: // :TODO: we really need more crazy complex cases.
138:
139: // //////////////////////////////////////////////////////////////////
140:
141: // The rest of these aren't that complex, but they are <i>somewhat</i>
142: // complex, and they expose weakness in dealing with queries that match
143: // with scores of 0 wrapped in other queries
144:
145: public void testT3() throws Exception {
146: bqtest("w1^0.0", new int[] { 0, 1, 2, 3 });
147: }
148:
149: public void testMA3() throws Exception {
150: Query q = new MatchAllDocsQuery();
151: q.setBoost(0);
152: bqtest(q, new int[] { 0, 1, 2, 3 });
153: }
154:
155: public void testFQ5() throws Exception {
156: bqtest(new FilteredQuery(qp.parse("xx^0"), new ItemizedFilter(
157: new int[] { 1, 3 })), new int[] { 3 });
158: }
159:
160: public void testCSQ4() throws Exception {
161: Query q = new ConstantScoreQuery(new ItemizedFilter(
162: new int[] { 3 }));
163: q.setBoost(0);
164: bqtest(q, new int[] { 3 });
165: }
166:
167: public void testDMQ10() throws Exception {
168: DisjunctionMaxQuery q = new DisjunctionMaxQuery(0.5f);
169: q.add(qp.parse("yy w5^100"));
170: q.add(qp.parse("xx^0"));
171: q.setBoost(0.0f);
172: bqtest(q, new int[] { 0, 2, 3 });
173: }
174:
175: public void testMPQ7() throws Exception {
176: MultiPhraseQuery q = new MultiPhraseQuery();
177: q.add(ta(new String[] { "w1" }));
178: q.add(ta(new String[] { "w2" }));
179: q.setSlop(1);
180: q.setBoost(0.0f);
181: bqtest(q, new int[] { 0, 1, 2 });
182: }
183:
184: public void testBQ12() throws Exception {
185: // NOTE: using qtest not bqtest
186: qtest("w1 w2^0.0", new int[] { 0, 1, 2, 3 });
187: }
188:
189: public void testBQ13() throws Exception {
190: // NOTE: using qtest not bqtest
191: qtest("w1 -w5^0.0", new int[] { 1, 2, 3 });
192: }
193:
194: public void testBQ18() throws Exception {
195: // NOTE: using qtest not bqtest
196: qtest("+w1^0.0 w2", new int[] { 0, 1, 2, 3 });
197: }
198:
199: public void testBQ21() throws Exception {
200: bqtest("(+w1 w2)^0.0", new int[] { 0, 1, 2, 3 });
201: }
202:
203: public void testBQ22() throws Exception {
204: bqtest("(+w1^0.0 w2)^0.0", new int[] { 0, 1, 2, 3 });
205: }
206:
207: public void testST3() throws Exception {
208: SpanQuery q = st("w1");
209: q.setBoost(0);
210: bqtest(q, new int[] { 0, 1, 2, 3 });
211: }
212:
213: public void testST6() throws Exception {
214: SpanQuery q = st("xx");
215: q.setBoost(0);
216: qtest(q, new int[] { 2, 3 });
217: }
218:
219: public void testSF3() throws Exception {
220: SpanQuery q = sf(("w1"), 1);
221: q.setBoost(0);
222: bqtest(q, new int[] { 0, 1, 2, 3 });
223: }
224:
225: public void testSF7() throws Exception {
226: SpanQuery q = sf(("xx"), 3);
227: q.setBoost(0);
228: bqtest(q, new int[] { 2, 3 });
229: }
230:
231: public void testSNot3() throws Exception {
232: SpanQuery q = snot(sf("w1", 10), st("QQ"));
233: q.setBoost(0);
234: bqtest(q, new int[] { 0, 1, 2, 3 });
235: }
236:
237: public void testSNot6() throws Exception {
238: SpanQuery q = snot(sf("w1", 10), st("xx"));
239: q.setBoost(0);
240: bqtest(q, new int[] { 0, 1, 2, 3 });
241: }
242:
243: public void testSNot8() throws Exception {
244: // NOTE: using qtest not bqtest
245: SpanQuery f = snear("w1", "w3", 10, true);
246: f.setBoost(0);
247: SpanQuery q = snot(f, st("xx"));
248: qtest(q, new int[] { 0, 1, 3 });
249: }
250:
251: public void testSNot9() throws Exception {
252: // NOTE: using qtest not bqtest
253: SpanQuery t = st("xx");
254: t.setBoost(0);
255: SpanQuery q = snot(snear("w1", "w3", 10, true), t);
256: qtest(q, new int[] { 0, 1, 3 });
257: }
258:
259: }
|