pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / contrib / highlighter / src / test / org / apache / lucene / search / vectorhighlight / FieldQueryTest.java
1 package org.apache.lucene.search.vectorhighlight;
2 /**
3  * Licensed to the Apache Software Foundation (ASF) under one or more
4  * contributor license agreements.  See the NOTICE file distributed with
5  * this work for additional information regarding copyright ownership.
6  * The ASF licenses this file to You under the Apache License, Version 2.0
7  * (the "License"); you may not use this file except in compliance with
8  * the License.  You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 import java.io.IOException;
20 import java.util.ArrayList;
21 import java.util.HashSet;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Set;
25
26 import org.apache.lucene.index.Term;
27 import org.apache.lucene.search.BooleanQuery;
28 import org.apache.lucene.search.PrefixQuery;
29 import org.apache.lucene.search.Query;
30 import org.apache.lucene.search.BooleanClause.Occur;
31 import org.apache.lucene.search.TermQuery;
32 import org.apache.lucene.search.TermRangeQuery;
33 import org.apache.lucene.search.WildcardQuery;
34 import org.apache.lucene.search.regex.RegexQuery;
35 import org.apache.lucene.search.vectorhighlight.FieldQuery.QueryPhraseMap;
36 import org.apache.lucene.search.vectorhighlight.FieldTermStack.TermInfo;
37
38 public class FieldQueryTest extends AbstractTestCase {
39
40   public void testFlattenBoolean() throws Exception {
41     Query query = paW.parse( "A AND B OR C NOT (D AND E)" );
42     FieldQuery fq = new FieldQuery( query, true, true );
43     Set<Query> flatQueries = new HashSet<Query>();
44     fq.flatten( query, reader, flatQueries );
45     assertCollectionQueries( flatQueries, tq( "A" ), tq( "B" ), tq( "C" ) );
46   }
47
48   public void testFlattenDisjunctionMaxQuery() throws Exception {
49     Query query = dmq( tq( "A" ), tq( "B" ), pqF( "C", "D" ) );
50     FieldQuery fq = new FieldQuery( query, true, true );
51     Set<Query> flatQueries = new HashSet<Query>();
52     fq.flatten( query, reader, flatQueries );
53     assertCollectionQueries( flatQueries, tq( "A" ), tq( "B" ), pqF( "C", "D" ) );
54   }
55
56   public void testFlattenTermAndPhrase() throws Exception {
57     Query query = paW.parse( "A AND \"B C\"" );
58     FieldQuery fq = new FieldQuery( query, true, true );
59     Set<Query> flatQueries = new HashSet<Query>();
60     fq.flatten( query, reader, flatQueries );
61     assertCollectionQueries( flatQueries, tq( "A" ), pqF( "B", "C" ) );
62   }
63
64   public void testFlattenTermAndPhrase2gram() throws Exception {
65     Query query = paB.parse( "AA AND \"BCD\" OR \"EFGH\"" );
66     FieldQuery fq = new FieldQuery( query, true, true );
67     Set<Query> flatQueries = new HashSet<Query>();
68     fq.flatten( query, reader, flatQueries );
69     assertCollectionQueries( flatQueries, tq( "AA" ), pqF( "BC", "CD" ), pqF( "EF", "FG", "GH" ) );
70   }
71
72   public void testFlatten1TermPhrase() throws Exception {
73     Query query = pqF( "A" );
74     FieldQuery fq = new FieldQuery( query, true, true );
75     Set<Query> flatQueries = new HashSet<Query>();
76     fq.flatten( query, reader, flatQueries );
77     assertCollectionQueries( flatQueries, tq( "A" ) );
78   }
79
80   public void testExpand() throws Exception {
81     Query dummy = pqF( "DUMMY" );
82     FieldQuery fq = new FieldQuery( dummy, true, true );
83
84     // "a b","b c" => "a b","b c","a b c"
85     Set<Query> flatQueries = new HashSet<Query>();
86     flatQueries.add( pqF( "a", "b" ) );
87     flatQueries.add( pqF( "b", "c" ) );
88     assertCollectionQueries( fq.expand( flatQueries ),
89         pqF( "a", "b" ), pqF( "b", "c" ), pqF( "a", "b", "c" ) );
90
91     // "a b","b c d" => "a b","b c d","a b c d"
92     flatQueries = new HashSet<Query>();
93     flatQueries.add( pqF( "a", "b" ) );
94     flatQueries.add( pqF( "b", "c", "d" ) );
95     assertCollectionQueries( fq.expand( flatQueries ),
96         pqF( "a", "b" ), pqF( "b", "c", "d" ), pqF( "a", "b", "c", "d" ) );
97
98     // "a b c","b c d" => "a b c","b c d","a b c d"
99     flatQueries = new HashSet<Query>();
100     flatQueries.add( pqF( "a", "b", "c" ) );
101     flatQueries.add( pqF( "b", "c", "d" ) );
102     assertCollectionQueries( fq.expand( flatQueries ),
103         pqF( "a", "b", "c" ), pqF( "b", "c", "d" ), pqF( "a", "b", "c", "d" ) );
104
105     // "a b c","c d e" => "a b c","c d e","a b c d e"
106     flatQueries = new HashSet<Query>();
107     flatQueries.add( pqF( "a", "b", "c" ) );
108     flatQueries.add( pqF( "c", "d", "e" ) );
109     assertCollectionQueries( fq.expand( flatQueries ),
110         pqF( "a", "b", "c" ), pqF( "c", "d", "e" ), pqF( "a", "b", "c", "d", "e" ) );
111
112     // "a b c d","b c" => "a b c d","b c"
113     flatQueries = new HashSet<Query>();
114     flatQueries.add( pqF( "a", "b", "c", "d" ) );
115     flatQueries.add( pqF( "b", "c" ) );
116     assertCollectionQueries( fq.expand( flatQueries ),
117         pqF( "a", "b", "c", "d" ), pqF( "b", "c" ) );
118
119     // "a b b","b c" => "a b b","b c","a b b c"
120     flatQueries = new HashSet<Query>();
121     flatQueries.add( pqF( "a", "b", "b" ) );
122     flatQueries.add( pqF( "b", "c" ) );
123     assertCollectionQueries( fq.expand( flatQueries ),
124         pqF( "a", "b", "b" ), pqF( "b", "c" ), pqF( "a", "b", "b", "c" ) );
125
126     // "a b","b a" => "a b","b a","a b a", "b a b"
127     flatQueries = new HashSet<Query>();
128     flatQueries.add( pqF( "a", "b" ) );
129     flatQueries.add( pqF( "b", "a" ) );
130     assertCollectionQueries( fq.expand( flatQueries ),
131         pqF( "a", "b" ), pqF( "b", "a" ), pqF( "a", "b", "a" ), pqF( "b", "a", "b" ) );
132
133     // "a b","a b c" => "a b","a b c"
134     flatQueries = new HashSet<Query>();
135     flatQueries.add( pqF( "a", "b" ) );
136     flatQueries.add( pqF( "a", "b", "c" ) );
137     assertCollectionQueries( fq.expand( flatQueries ),
138         pqF( "a", "b" ), pqF( "a", "b", "c" ) );
139   }
140
141   public void testNoExpand() throws Exception {
142     Query dummy = pqF( "DUMMY" );
143     FieldQuery fq = new FieldQuery( dummy, true, true );
144
145     // "a b","c d" => "a b","c d"
146     Set<Query> flatQueries = new HashSet<Query>();
147     flatQueries.add( pqF( "a", "b" ) );
148     flatQueries.add( pqF( "c", "d" ) );
149     assertCollectionQueries( fq.expand( flatQueries ),
150         pqF( "a", "b" ), pqF( "c", "d" ) );
151
152     // "a","a b" => "a", "a b"
153     flatQueries = new HashSet<Query>();
154     flatQueries.add( tq( "a" ) );
155     flatQueries.add( pqF( "a", "b" ) );
156     assertCollectionQueries( fq.expand( flatQueries ),
157         tq( "a" ), pqF( "a", "b" ) );
158
159     // "a b","b" => "a b", "b"
160     flatQueries = new HashSet<Query>();
161     flatQueries.add( pqF( "a", "b" ) );
162     flatQueries.add( tq( "b" ) );
163     assertCollectionQueries( fq.expand( flatQueries ),
164         pqF( "a", "b" ), tq( "b" ) );
165
166     // "a b c","b c" => "a b c","b c"
167     flatQueries = new HashSet<Query>();
168     flatQueries.add( pqF( "a", "b", "c" ) );
169     flatQueries.add( pqF( "b", "c" ) );
170     assertCollectionQueries( fq.expand( flatQueries ),
171         pqF( "a", "b", "c" ), pqF( "b", "c" ) );
172
173     // "a b","a b c" => "a b","a b c"
174     flatQueries = new HashSet<Query>();
175     flatQueries.add( pqF( "a", "b" ) );
176     flatQueries.add( pqF( "a", "b", "c" ) );
177     assertCollectionQueries( fq.expand( flatQueries ),
178         pqF( "a", "b" ), pqF( "a", "b", "c" ) );
179
180     // "a b c","b d e" => "a b c","b d e"
181     flatQueries = new HashSet<Query>();
182     flatQueries.add( pqF( "a", "b", "c" ) );
183     flatQueries.add( pqF( "b", "d", "e" ) );
184     assertCollectionQueries( fq.expand( flatQueries ),
185         pqF( "a", "b", "c" ), pqF( "b", "d", "e" ) );
186   }
187
188   public void testExpandNotFieldMatch() throws Exception {
189     Query dummy = pqF( "DUMMY" );
190     FieldQuery fq = new FieldQuery( dummy, true, false );
191
192     // f1:"a b",f2:"b c" => f1:"a b",f2:"b c",f1:"a b c"
193     Set<Query> flatQueries = new HashSet<Query>();
194     flatQueries.add( pq( F1, "a", "b" ) );
195     flatQueries.add( pq( F2, "b", "c" ) );
196     assertCollectionQueries( fq.expand( flatQueries ),
197         pq( F1, "a", "b" ), pq( F2, "b", "c" ), pq( F1, "a", "b", "c" ) );
198   }
199
200   public void testGetFieldTermMap() throws Exception {
201     Query query = tq( "a" );
202     FieldQuery fq = new FieldQuery( query, true, true );
203     
204     QueryPhraseMap pqm = fq.getFieldTermMap( F, "a" );
205     assertNotNull( pqm );
206     assertTrue( pqm.isTerminal() );
207     
208     pqm = fq.getFieldTermMap( F, "b" );
209     assertNull( pqm );
210     
211     pqm = fq.getFieldTermMap( F1, "a" );
212     assertNull( pqm );
213   }
214
215   public void testGetRootMap() throws Exception {
216     Query dummy = pqF( "DUMMY" );
217     FieldQuery fq = new FieldQuery( dummy, true, true );
218
219     QueryPhraseMap rootMap1 = fq.getRootMap( tq( "a" ) );
220     QueryPhraseMap rootMap2 = fq.getRootMap( tq( "a" ) );
221     assertTrue( rootMap1 == rootMap2 );
222     QueryPhraseMap rootMap3 = fq.getRootMap( tq( "b" ) );
223     assertTrue( rootMap1 == rootMap3 );
224     QueryPhraseMap rootMap4 = fq.getRootMap( tq( F1, "b" ) );
225     assertFalse( rootMap4 == rootMap3 );
226   }
227
228   public void testGetRootMapNotFieldMatch() throws Exception {
229     Query dummy = pqF( "DUMMY" );
230     FieldQuery fq = new FieldQuery( dummy, true, false );
231
232     QueryPhraseMap rootMap1 = fq.getRootMap( tq( "a" ) );
233     QueryPhraseMap rootMap2 = fq.getRootMap( tq( "a" ) );
234     assertTrue( rootMap1 == rootMap2 );
235     QueryPhraseMap rootMap3 = fq.getRootMap( tq( "b" ) );
236     assertTrue( rootMap1 == rootMap3 );
237     QueryPhraseMap rootMap4 = fq.getRootMap( tq( F1, "b" ) );
238     assertTrue( rootMap4 == rootMap3 );
239   }
240
241   public void testGetTermSet() throws Exception {
242     Query query = paW.parse( "A AND B OR x:C NOT (D AND E)" );
243     FieldQuery fq = new FieldQuery( query, true, true );
244     assertEquals( 2, fq.termSetMap.size() );
245     Set<String> termSet = fq.getTermSet( F );
246     assertEquals( 2, termSet.size() );
247     assertTrue( termSet.contains( "A" ) );
248     assertTrue( termSet.contains( "B" ) );
249     termSet = fq.getTermSet( "x" );
250     assertEquals( 1, termSet.size() );
251     assertTrue( termSet.contains( "C" ) );
252     termSet = fq.getTermSet( "y" );
253     assertNull( termSet );
254   }
255   
256   public void testQueryPhraseMap1Term() throws Exception {
257     Query query = tq( "a" );
258     
259     // phraseHighlight = true, fieldMatch = true
260     FieldQuery fq = new FieldQuery( query, true, true );
261     Map<String, QueryPhraseMap> map = fq.rootMaps;
262     assertEquals( 1, map.size() );
263     assertNull( map.get( null ) );
264     assertNotNull( map.get( F ) );
265     QueryPhraseMap qpm = map.get( F );
266     assertEquals( 1, qpm.subMap.size() );
267     assertTrue( qpm.subMap.get( "a" ) != null );
268     assertTrue( qpm.subMap.get( "a" ).terminal );
269     assertEquals( 1F, qpm.subMap.get( "a" ).boost, 0);
270     
271     // phraseHighlight = true, fieldMatch = false
272     fq = new FieldQuery( query, true, false );
273     map = fq.rootMaps;
274     assertEquals( 1, map.size() );
275     assertNull( map.get( F ) );
276     assertNotNull( map.get( null ) );
277     qpm = map.get( null );
278     assertEquals( 1, qpm.subMap.size() );
279     assertTrue( qpm.subMap.get( "a" ) != null );
280     assertTrue( qpm.subMap.get( "a" ).terminal );
281     assertEquals( 1F, qpm.subMap.get( "a" ).boost, 0);
282     
283     // phraseHighlight = false, fieldMatch = true
284     fq = new FieldQuery( query, false, true );
285     map = fq.rootMaps;
286     assertEquals( 1, map.size() );
287     assertNull( map.get( null ) );
288     assertNotNull( map.get( F ) );
289     qpm = map.get( F );
290     assertEquals( 1, qpm.subMap.size() );
291     assertTrue( qpm.subMap.get( "a" ) != null );
292     assertTrue( qpm.subMap.get( "a" ).terminal );
293     assertEquals( 1F, qpm.subMap.get( "a" ).boost, 0);
294     
295     // phraseHighlight = false, fieldMatch = false
296     fq = new FieldQuery( query, false, false );
297     map = fq.rootMaps;
298     assertEquals( 1, map.size() );
299     assertNull( map.get( F ) );
300     assertNotNull( map.get( null ) );
301     qpm = map.get( null );
302     assertEquals( 1, qpm.subMap.size() );
303     assertTrue( qpm.subMap.get( "a" ) != null );
304     assertTrue( qpm.subMap.get( "a" ).terminal );
305     assertEquals( 1F, qpm.subMap.get( "a" ).boost, 0);
306     
307     // boost != 1
308     query = tq( 2, "a" );
309     fq = new FieldQuery( query, true, true );
310     map = fq.rootMaps;
311     qpm = map.get( F );
312     assertEquals( 2F, qpm.subMap.get( "a" ).boost, 0);
313   }
314   
315   public void testQueryPhraseMap1Phrase() throws Exception {
316     Query query = pqF( "a", "b" );
317     
318     // phraseHighlight = true, fieldMatch = true
319     FieldQuery fq = new FieldQuery( query, true, true );
320     Map<String, QueryPhraseMap> map = fq.rootMaps;
321     assertEquals( 1, map.size() );
322     assertNull( map.get( null ) );
323     assertNotNull( map.get( F ) );
324     QueryPhraseMap qpm = map.get( F );
325     assertEquals( 1, qpm.subMap.size() );
326     assertNotNull( qpm.subMap.get( "a" ) );
327     QueryPhraseMap qpm2 = qpm.subMap.get( "a" );
328     assertFalse( qpm2.terminal );
329     assertEquals( 1, qpm2.subMap.size() );
330     assertNotNull( qpm2.subMap.get( "b" ) );
331     QueryPhraseMap qpm3 = qpm2.subMap.get( "b" );
332     assertTrue( qpm3.terminal );
333     assertEquals( 1F, qpm3.boost, 0);
334     
335     // phraseHighlight = true, fieldMatch = false
336     fq = new FieldQuery( query, true, false );
337     map = fq.rootMaps;
338     assertEquals( 1, map.size() );
339     assertNull( map.get( F ) );
340     assertNotNull( map.get( null ) );
341     qpm = map.get( null );
342     assertEquals( 1, qpm.subMap.size() );
343     assertNotNull( qpm.subMap.get( "a" ) );
344     qpm2 = qpm.subMap.get( "a" );
345     assertFalse( qpm2.terminal );
346     assertEquals( 1, qpm2.subMap.size() );
347     assertNotNull( qpm2.subMap.get( "b" ) );
348     qpm3 = qpm2.subMap.get( "b" );
349     assertTrue( qpm3.terminal );
350     assertEquals( 1F, qpm3.boost, 0);
351     
352     // phraseHighlight = false, fieldMatch = true
353     fq = new FieldQuery( query, false, true );
354     map = fq.rootMaps;
355     assertEquals( 1, map.size() );
356     assertNull( map.get( null ) );
357     assertNotNull( map.get( F ) );
358     qpm = map.get( F );
359     assertEquals( 2, qpm.subMap.size() );
360     assertNotNull( qpm.subMap.get( "a" ) );
361     qpm2 = qpm.subMap.get( "a" );
362     assertTrue( qpm2.terminal );
363     assertEquals( 1F, qpm2.boost, 0);
364     assertEquals( 1, qpm2.subMap.size() );
365     assertNotNull( qpm2.subMap.get( "b" ) );
366     qpm3 = qpm2.subMap.get( "b" );
367     assertTrue( qpm3.terminal );
368     assertEquals( 1F, qpm3.boost, 0);
369
370     assertNotNull( qpm.subMap.get( "b" ) );
371     qpm2 = qpm.subMap.get( "b" );
372     assertTrue( qpm2.terminal );
373     assertEquals( 1F, qpm2.boost, 0);
374     
375     // phraseHighlight = false, fieldMatch = false
376     fq = new FieldQuery( query, false, false );
377     map = fq.rootMaps;
378     assertEquals( 1, map.size() );
379     assertNull( map.get( F ) );
380     assertNotNull( map.get( null ) );
381     qpm = map.get( null );
382     assertEquals( 2, qpm.subMap.size() );
383     assertNotNull( qpm.subMap.get( "a" ) );
384     qpm2 = qpm.subMap.get( "a" );
385     assertTrue( qpm2.terminal );
386     assertEquals( 1F, qpm2.boost, 0);
387     assertEquals( 1, qpm2.subMap.size() );
388     assertNotNull( qpm2.subMap.get( "b" ) );
389     qpm3 = qpm2.subMap.get( "b" );
390     assertTrue( qpm3.terminal );
391     assertEquals( 1F, qpm3.boost, 0);
392
393     assertNotNull( qpm.subMap.get( "b" ) );
394     qpm2 = qpm.subMap.get( "b" );
395     assertTrue( qpm2.terminal );
396     assertEquals( 1F, qpm2.boost, 0);
397
398     // boost != 1
399     query = pqF( 2, "a", "b" );
400     // phraseHighlight = false, fieldMatch = false
401     fq = new FieldQuery( query, false, false );
402     map = fq.rootMaps;
403     qpm = map.get( null );
404     qpm2 = qpm.subMap.get( "a" );
405     assertEquals( 2F, qpm2.boost, 0);
406     qpm3 = qpm2.subMap.get( "b" );
407     assertEquals( 2F, qpm3.boost, 0);
408     qpm2 = qpm.subMap.get( "b" );
409     assertEquals( 2F, qpm2.boost, 0);
410   }
411   
412   public void testQueryPhraseMap1PhraseAnother() throws Exception {
413     Query query = pqF( "search", "engines" );
414     
415     // phraseHighlight = true, fieldMatch = true
416     FieldQuery fq = new FieldQuery( query, true, true );
417     Map<String, QueryPhraseMap> map = fq.rootMaps;
418     assertEquals( 1, map.size() );
419     assertNull( map.get( null ) );
420     assertNotNull( map.get( F ) );
421     QueryPhraseMap qpm = map.get( F );
422     assertEquals( 1, qpm.subMap.size() );
423     assertNotNull( qpm.subMap.get( "search" ) );
424     QueryPhraseMap qpm2 = qpm.subMap.get( "search" );
425     assertFalse( qpm2.terminal );
426     assertEquals( 1, qpm2.subMap.size() );
427     assertNotNull( qpm2.subMap.get( "engines" ) );
428     QueryPhraseMap qpm3 = qpm2.subMap.get( "engines" );
429     assertTrue( qpm3.terminal );
430     assertEquals( 1F, qpm3.boost, 0);
431   }
432   
433   public void testQueryPhraseMap2Phrases() throws Exception {
434     BooleanQuery query = new BooleanQuery();
435     query.add( pqF( "a", "b" ), Occur.SHOULD );
436     query.add( pqF( 2, "c", "d" ), Occur.SHOULD );
437     
438     // phraseHighlight = true, fieldMatch = true
439     FieldQuery fq = new FieldQuery( query, true, true );
440     Map<String, QueryPhraseMap> map = fq.rootMaps;
441     assertEquals( 1, map.size() );
442     assertNull( map.get( null ) );
443     assertNotNull( map.get( F ) );
444     QueryPhraseMap qpm = map.get( F );
445     assertEquals( 2, qpm.subMap.size() );
446
447     // "a b"
448     assertNotNull( qpm.subMap.get( "a" ) );
449     QueryPhraseMap qpm2 = qpm.subMap.get( "a" );
450     assertFalse( qpm2.terminal );
451     assertEquals( 1, qpm2.subMap.size() );
452     assertNotNull( qpm2.subMap.get( "b" ) );
453     QueryPhraseMap qpm3 = qpm2.subMap.get( "b" );
454     assertTrue( qpm3.terminal );
455     assertEquals( 1F, qpm3.boost, 0);
456
457     // "c d"^2
458     assertNotNull( qpm.subMap.get( "c" ) );
459     qpm2 = qpm.subMap.get( "c" );
460     assertFalse( qpm2.terminal );
461     assertEquals( 1, qpm2.subMap.size() );
462     assertNotNull( qpm2.subMap.get( "d" ) );
463     qpm3 = qpm2.subMap.get( "d" );
464     assertTrue( qpm3.terminal );
465     assertEquals( 2F, qpm3.boost, 0);
466   }
467   
468   public void testQueryPhraseMap2PhrasesFields() throws Exception {
469     BooleanQuery query = new BooleanQuery();
470     query.add( pq( F1, "a", "b" ), Occur.SHOULD );
471     query.add( pq( 2F, F2, "c", "d" ), Occur.SHOULD );
472     
473     // phraseHighlight = true, fieldMatch = true
474     FieldQuery fq = new FieldQuery( query, true, true );
475     Map<String, QueryPhraseMap> map = fq.rootMaps;
476     assertEquals( 2, map.size() );
477     assertNull( map.get( null ) );
478
479     // "a b"
480     assertNotNull( map.get( F1 ) );
481     QueryPhraseMap qpm = map.get( F1 );
482     assertEquals( 1, qpm.subMap.size() );
483     assertNotNull( qpm.subMap.get( "a" ) );
484     QueryPhraseMap qpm2 = qpm.subMap.get( "a" );
485     assertFalse( qpm2.terminal );
486     assertEquals( 1, qpm2.subMap.size() );
487     assertNotNull( qpm2.subMap.get( "b" ) );
488     QueryPhraseMap qpm3 = qpm2.subMap.get( "b" );
489     assertTrue( qpm3.terminal );
490     assertEquals( 1F, qpm3.boost, 0);
491
492     // "c d"^2
493     assertNotNull( map.get( F2 ) );
494     qpm = map.get( F2 );
495     assertEquals( 1, qpm.subMap.size() );
496     assertNotNull( qpm.subMap.get( "c" ) );
497     qpm2 = qpm.subMap.get( "c" );
498     assertFalse( qpm2.terminal );
499     assertEquals( 1, qpm2.subMap.size() );
500     assertNotNull( qpm2.subMap.get( "d" ) );
501     qpm3 = qpm2.subMap.get( "d" );
502     assertTrue( qpm3.terminal );
503     assertEquals( 2F, qpm3.boost, 0);
504     
505     // phraseHighlight = true, fieldMatch = false
506     fq = new FieldQuery( query, true, false );
507     map = fq.rootMaps;
508     assertEquals( 1, map.size() );
509     assertNull( map.get( F1 ) );
510     assertNull( map.get( F2 ) );
511     assertNotNull( map.get( null ) );
512     qpm = map.get( null );
513     assertEquals( 2, qpm.subMap.size() );
514
515     // "a b"
516     assertNotNull( qpm.subMap.get( "a" ) );
517     qpm2 = qpm.subMap.get( "a" );
518     assertFalse( qpm2.terminal );
519     assertEquals( 1, qpm2.subMap.size() );
520     assertNotNull( qpm2.subMap.get( "b" ) );
521     qpm3 = qpm2.subMap.get( "b" );
522     assertTrue( qpm3.terminal );
523     assertEquals( 1F, qpm3.boost, 0);
524
525     // "c d"^2
526     assertNotNull( qpm.subMap.get( "c" ) );
527     qpm2 = qpm.subMap.get( "c" );
528     assertFalse( qpm2.terminal );
529     assertEquals( 1, qpm2.subMap.size() );
530     assertNotNull( qpm2.subMap.get( "d" ) );
531     qpm3 = qpm2.subMap.get( "d" );
532     assertTrue( qpm3.terminal );
533     assertEquals( 2F, qpm3.boost, 0);
534   }
535   
536   /*
537    * <t>...terminal
538    * 
539    * a-b-c-<t>
540    *     +-d-<t>
541    * b-c-d-<t>
542    * +-d-<t>
543    */
544   public void testQueryPhraseMapOverlapPhrases() throws Exception {
545     BooleanQuery query = new BooleanQuery();
546     query.add( pqF( "a", "b", "c" ), Occur.SHOULD );
547     query.add( pqF( 2, "b", "c", "d" ), Occur.SHOULD );
548     query.add( pqF( 3, "b", "d" ), Occur.SHOULD );
549     
550     // phraseHighlight = true, fieldMatch = true
551     FieldQuery fq = new FieldQuery( query, true, true );
552     Map<String, QueryPhraseMap> map = fq.rootMaps;
553     assertEquals( 1, map.size() );
554     assertNull( map.get( null ) );
555     assertNotNull( map.get( F ) );
556     QueryPhraseMap qpm = map.get( F );
557     assertEquals( 2, qpm.subMap.size() );
558
559     // "a b c"
560     assertNotNull( qpm.subMap.get( "a" ) );
561     QueryPhraseMap qpm2 = qpm.subMap.get( "a" );
562     assertFalse( qpm2.terminal );
563     assertEquals( 1, qpm2.subMap.size() );
564     assertNotNull( qpm2.subMap.get( "b" ) );
565     QueryPhraseMap qpm3 = qpm2.subMap.get( "b" );
566     assertFalse( qpm3.terminal );
567     assertEquals( 1, qpm3.subMap.size() );
568     assertNotNull( qpm3.subMap.get( "c" ) );
569     QueryPhraseMap qpm4 = qpm3.subMap.get( "c" );
570     assertTrue( qpm4.terminal );
571     assertEquals( 1F, qpm4.boost, 0);
572     assertNotNull( qpm4.subMap.get( "d" ) );
573     QueryPhraseMap qpm5 = qpm4.subMap.get( "d" );
574     assertTrue( qpm5.terminal );
575     assertEquals( 1F, qpm5.boost, 0);
576
577     // "b c d"^2, "b d"^3
578     assertNotNull( qpm.subMap.get( "b" ) );
579     qpm2 = qpm.subMap.get( "b" );
580     assertFalse( qpm2.terminal );
581     assertEquals( 2, qpm2.subMap.size() );
582     assertNotNull( qpm2.subMap.get( "c" ) );
583     qpm3 = qpm2.subMap.get( "c" );
584     assertFalse( qpm3.terminal );
585     assertEquals( 1, qpm3.subMap.size() );
586     assertNotNull( qpm3.subMap.get( "d" ) );
587     qpm4 = qpm3.subMap.get( "d" );
588     assertTrue( qpm4.terminal );
589     assertEquals( 2F, qpm4.boost, 0);
590     assertNotNull( qpm2.subMap.get( "d" ) );
591     qpm3 = qpm2.subMap.get( "d" );
592     assertTrue( qpm3.terminal );
593     assertEquals( 3F, qpm3.boost, 0);
594   }
595   
596   /*
597    * <t>...terminal
598    * 
599    * a-b-<t>
600    *   +-c-<t>
601    */
602   public void testQueryPhraseMapOverlapPhrases2() throws Exception {
603     BooleanQuery query = new BooleanQuery();
604     query.add( pqF( "a", "b" ), Occur.SHOULD );
605     query.add( pqF( 2, "a", "b", "c" ), Occur.SHOULD );
606     
607     // phraseHighlight = true, fieldMatch = true
608     FieldQuery fq = new FieldQuery( query, true, true );
609     Map<String, QueryPhraseMap> map = fq.rootMaps;
610     assertEquals( 1, map.size() );
611     assertNull( map.get( null ) );
612     assertNotNull( map.get( F ) );
613     QueryPhraseMap qpm = map.get( F );
614     assertEquals( 1, qpm.subMap.size() );
615
616     // "a b"
617     assertNotNull( qpm.subMap.get( "a" ) );
618     QueryPhraseMap qpm2 = qpm.subMap.get( "a" );
619     assertFalse( qpm2.terminal );
620     assertEquals( 1, qpm2.subMap.size() );
621     assertNotNull( qpm2.subMap.get( "b" ) );
622     QueryPhraseMap qpm3 = qpm2.subMap.get( "b" );
623     assertTrue( qpm3.terminal );
624     assertEquals( 1F, qpm3.boost, 0);
625
626     // "a b c"^2
627     assertEquals( 1, qpm3.subMap.size() );
628     assertNotNull( qpm3.subMap.get( "c" ) );
629     QueryPhraseMap qpm4 = qpm3.subMap.get( "c" );
630     assertTrue( qpm4.terminal );
631     assertEquals( 2F, qpm4.boost, 0);
632   }
633   
634   /*
635    * <t>...terminal
636    * 
637    * a-a-a-<t>
638    *     +-a-<t>
639    *       +-a-<t>
640    *         +-a-<t>
641    */
642   public void testQueryPhraseMapOverlapPhrases3() throws Exception {
643     BooleanQuery query = new BooleanQuery();
644     query.add( pqF( "a", "a", "a", "a" ), Occur.SHOULD );
645     query.add( pqF( 2, "a", "a", "a" ), Occur.SHOULD );
646     
647     // phraseHighlight = true, fieldMatch = true
648     FieldQuery fq = new FieldQuery( query, true, true );
649     Map<String, QueryPhraseMap> map = fq.rootMaps;
650     assertEquals( 1, map.size() );
651     assertNull( map.get( null ) );
652     assertNotNull( map.get( F ) );
653     QueryPhraseMap qpm = map.get( F );
654     assertEquals( 1, qpm.subMap.size() );
655
656     // "a a a"
657     assertNotNull( qpm.subMap.get( "a" ) );
658     QueryPhraseMap qpm2 = qpm.subMap.get( "a" );
659     assertFalse( qpm2.terminal );
660     assertEquals( 1, qpm2.subMap.size() );
661     assertNotNull( qpm2.subMap.get( "a" ) );
662     QueryPhraseMap qpm3 = qpm2.subMap.get( "a" );
663     assertFalse( qpm3.terminal );
664     assertEquals( 1, qpm3.subMap.size() );
665     assertNotNull( qpm3.subMap.get( "a" ) );
666     QueryPhraseMap qpm4 = qpm3.subMap.get( "a" );
667     assertTrue( qpm4.terminal );
668
669     // "a a a a"
670     assertEquals( 1, qpm4.subMap.size() );
671     assertNotNull( qpm4.subMap.get( "a" ) );
672     QueryPhraseMap qpm5 = qpm4.subMap.get( "a" );
673     assertTrue( qpm5.terminal );
674
675     // "a a a a a"
676     assertEquals( 1, qpm5.subMap.size() );
677     assertNotNull( qpm5.subMap.get( "a" ) );
678     QueryPhraseMap qpm6 = qpm5.subMap.get( "a" );
679     assertTrue( qpm6.terminal );
680
681     // "a a a a a a"
682     assertEquals( 1, qpm6.subMap.size() );
683     assertNotNull( qpm6.subMap.get( "a" ) );
684     QueryPhraseMap qpm7 = qpm6.subMap.get( "a" );
685     assertTrue( qpm7.terminal );
686   }
687   
688   public void testQueryPhraseMapOverlap2gram() throws Exception {
689     Query query = paB.parse( "\"abc\" AND \"bcd\"" );
690     
691     // phraseHighlight = true, fieldMatch = true
692     FieldQuery fq = new FieldQuery( query, true, true );
693     Map<String, QueryPhraseMap> map = fq.rootMaps;
694     assertEquals( 1, map.size() );
695     assertNull( map.get( null ) );
696     assertNotNull( map.get( F ) );
697     QueryPhraseMap qpm = map.get( F );
698     assertEquals( 2, qpm.subMap.size() );
699
700     // "ab bc"
701     assertNotNull( qpm.subMap.get( "ab" ) );
702     QueryPhraseMap qpm2 = qpm.subMap.get( "ab" );
703     assertFalse( qpm2.terminal );
704     assertEquals( 1, qpm2.subMap.size() );
705     assertNotNull( qpm2.subMap.get( "bc" ) );
706     QueryPhraseMap qpm3 = qpm2.subMap.get( "bc" );
707     assertTrue( qpm3.terminal );
708     assertEquals( 1F, qpm3.boost, 0);
709
710     // "ab bc cd"
711     assertEquals( 1, qpm3.subMap.size() );
712     assertNotNull( qpm3.subMap.get( "cd" ) );
713     QueryPhraseMap qpm4 = qpm3.subMap.get( "cd" );
714     assertTrue( qpm4.terminal );
715     assertEquals( 1F, qpm4.boost, 0);
716
717     // "bc cd"
718     assertNotNull( qpm.subMap.get( "bc" ) );
719     qpm2 = qpm.subMap.get( "bc" );
720     assertFalse( qpm2.terminal );
721     assertEquals( 1, qpm2.subMap.size() );
722     assertNotNull( qpm2.subMap.get( "cd" ) );
723     qpm3 = qpm2.subMap.get( "cd" );
724     assertTrue( qpm3.terminal );
725     assertEquals( 1F, qpm3.boost, 0);
726     
727     // phraseHighlight = false, fieldMatch = true
728     fq = new FieldQuery( query, false, true );
729     map = fq.rootMaps;
730     assertEquals( 1, map.size() );
731     assertNull( map.get( null ) );
732     assertNotNull( map.get( F ) );
733     qpm = map.get( F );
734     assertEquals( 3, qpm.subMap.size() );
735
736     // "ab bc"
737     assertNotNull( qpm.subMap.get( "ab" ) );
738     qpm2 = qpm.subMap.get( "ab" );
739     assertTrue( qpm2.terminal );
740     assertEquals( 1F, qpm2.boost, 0);
741     assertEquals( 1, qpm2.subMap.size() );
742     assertNotNull( qpm2.subMap.get( "bc" ) );
743     qpm3 = qpm2.subMap.get( "bc" );
744     assertTrue( qpm3.terminal );
745     assertEquals( 1F, qpm3.boost, 0);
746
747     // "ab bc cd"
748     assertEquals( 1, qpm3.subMap.size() );
749     assertNotNull( qpm3.subMap.get( "cd" ) );
750     qpm4 = qpm3.subMap.get( "cd" );
751     assertTrue( qpm4.terminal );
752     assertEquals( 1F, qpm4.boost, 0);
753
754     // "bc cd"
755     assertNotNull( qpm.subMap.get( "bc" ) );
756     qpm2 = qpm.subMap.get( "bc" );
757     assertTrue( qpm2.terminal );
758     assertEquals( 1F, qpm2.boost, 0);
759     assertEquals( 1, qpm2.subMap.size() );
760     assertNotNull( qpm2.subMap.get( "cd" ) );
761     qpm3 = qpm2.subMap.get( "cd" );
762     assertTrue( qpm3.terminal );
763     assertEquals( 1F, qpm3.boost, 0);
764
765     // "cd"
766     assertNotNull( qpm.subMap.get( "cd" ) );
767     qpm2 = qpm.subMap.get( "cd" );
768     assertTrue( qpm2.terminal );
769     assertEquals( 1F, qpm2.boost, 0);
770     assertEquals( 0, qpm2.subMap.size() );
771   }
772   
773   public void testSearchPhrase() throws Exception {
774     Query query = pqF( "a", "b", "c" );
775
776     // phraseHighlight = true, fieldMatch = true
777     FieldQuery fq = new FieldQuery( query, true, true );
778     
779     // "a"
780     List<TermInfo> phraseCandidate = new ArrayList<TermInfo>();
781     phraseCandidate.add( new TermInfo( "a", 0, 1, 0 ) );
782     assertNull( fq.searchPhrase( F, phraseCandidate ) );
783     // "a b"
784     phraseCandidate.add( new TermInfo( "b", 2, 3, 1 ) );
785     assertNull( fq.searchPhrase( F, phraseCandidate ) );
786     // "a b c"
787     phraseCandidate.add( new TermInfo( "c", 4, 5, 2 ) );
788     assertNotNull( fq.searchPhrase( F, phraseCandidate ) );
789     assertNull( fq.searchPhrase( "x", phraseCandidate ) );
790
791     // phraseHighlight = true, fieldMatch = false
792     fq = new FieldQuery( query, true, false );
793     
794     // "a b c"
795     assertNotNull( fq.searchPhrase( F, phraseCandidate ) );
796     assertNotNull( fq.searchPhrase( "x", phraseCandidate ) );
797
798     // phraseHighlight = false, fieldMatch = true
799     fq = new FieldQuery( query, false, true );
800     
801     // "a"
802     phraseCandidate.clear();
803     phraseCandidate.add( new TermInfo( "a", 0, 1, 0 ) );
804     assertNotNull( fq.searchPhrase( F, phraseCandidate ) );
805     // "a b"
806     phraseCandidate.add( new TermInfo( "b", 2, 3, 1 ) );
807     assertNull( fq.searchPhrase( F, phraseCandidate ) );
808     // "a b c"
809     phraseCandidate.add( new TermInfo( "c", 4, 5, 2 ) );
810     assertNotNull( fq.searchPhrase( F, phraseCandidate ) );
811     assertNull( fq.searchPhrase( "x", phraseCandidate ) );
812   }
813   
814   public void testSearchPhraseSlop() throws Exception {
815     // "a b c"~0
816     Query query = pqF( "a", "b", "c" );
817
818     // phraseHighlight = true, fieldMatch = true
819     FieldQuery fq = new FieldQuery( query, true, true );
820     
821     // "a b c" w/ position-gap = 2
822     List<TermInfo> phraseCandidate = new ArrayList<TermInfo>();
823     phraseCandidate.add( new TermInfo( "a", 0, 1, 0 ) );
824     phraseCandidate.add( new TermInfo( "b", 2, 3, 2 ) );
825     phraseCandidate.add( new TermInfo( "c", 4, 5, 4 ) );
826     assertNull( fq.searchPhrase( F, phraseCandidate ) );
827
828     // "a b c"~1
829     query = pqF( 1F, 1, "a", "b", "c" );
830
831     // phraseHighlight = true, fieldMatch = true
832     fq = new FieldQuery( query, true, true );
833     
834     // "a b c" w/ position-gap = 2
835     assertNotNull( fq.searchPhrase( F, phraseCandidate ) );
836     
837     // "a b c" w/ position-gap = 3
838     phraseCandidate.clear();
839     phraseCandidate.add( new TermInfo( "a", 0, 1, 0 ) );
840     phraseCandidate.add( new TermInfo( "b", 2, 3, 3 ) );
841     phraseCandidate.add( new TermInfo( "c", 4, 5, 6 ) );
842     assertNull( fq.searchPhrase( F, phraseCandidate ) );
843   }
844   
845   public void testHighlightQuery() throws Exception {
846     makeIndexStrMV();
847     defgMultiTermQueryTest(new WildcardQuery(new Term(F, "d*g")));
848   }
849
850   public void testPrefixQuery() throws Exception {
851     makeIndexStrMV();
852     defgMultiTermQueryTest(new PrefixQuery(new Term(F, "de")));
853   }
854   
855   public void testRegexQuery() throws Exception {
856     makeIndexStrMV();
857     Term term = new Term(F, "d[a-z].g");
858     defgMultiTermQueryTest(new RegexQuery(term));
859   }
860
861   public void testRangeQuery() throws Exception {
862     makeIndexStrMV();
863     defgMultiTermQueryTest(new TermRangeQuery (F, "d", "e", true, true));
864   }
865
866   private void defgMultiTermQueryTest(Query query) throws IOException {
867     FieldQuery fq = new FieldQuery( query, reader, true, true );
868     QueryPhraseMap qpm = fq.getFieldTermMap(F, "defg");
869     assertNotNull (qpm);
870     assertNull (fq.getFieldTermMap(F, "dog"));
871     List<TermInfo> phraseCandidate = new ArrayList<TermInfo>();
872     phraseCandidate.add( new TermInfo( "defg", 0, 12, 0 ) );
873     assertNotNull (fq.searchPhrase(F, phraseCandidate));
874   }
875   
876 }