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