| /* |
| * 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.vectorhighlight; |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.apache.lucene.index.Term; |
| import org.apache.lucene.search.BooleanClause.Occur; |
| import org.apache.lucene.search.BooleanQuery; |
| import org.apache.lucene.search.BoostQuery; |
| import org.apache.lucene.search.ConstantScoreQuery; |
| import org.apache.lucene.search.PrefixQuery; |
| import org.apache.lucene.search.Query; |
| import org.apache.lucene.search.QueryVisitor; |
| import org.apache.lucene.search.RegexpQuery; |
| import org.apache.lucene.search.TermQuery; |
| import org.apache.lucene.search.TermRangeQuery; |
| import org.apache.lucene.search.WildcardQuery; |
| import org.apache.lucene.search.vectorhighlight.FieldQuery.QueryPhraseMap; |
| import org.apache.lucene.search.vectorhighlight.FieldTermStack.TermInfo; |
| import org.apache.lucene.util.BytesRef; |
| |
| public class FieldQueryTest extends AbstractTestCase { |
| private float boost; |
| |
| /** |
| * Set boost to a random value each time it is called. |
| */ |
| private void initBoost() { |
| boost = usually() ? 1F : random().nextFloat() * 10000; |
| } |
| |
| public void testFlattenBoolean() throws Exception { |
| initBoost(); |
| BooleanQuery.Builder booleanQueryB = new BooleanQuery.Builder(); |
| booleanQueryB.add(tq("A"), Occur.MUST); |
| booleanQueryB.add(tq("B"), Occur.MUST); |
| booleanQueryB.add(tq("C"), Occur.SHOULD); |
| |
| BooleanQuery.Builder innerQuery = new BooleanQuery.Builder(); |
| innerQuery.add(tq("D"), Occur.MUST); |
| innerQuery.add(tq("E"), Occur.MUST); |
| booleanQueryB.add(innerQuery.build(), Occur.MUST_NOT); |
| |
| Query booleanQuery = booleanQueryB.build(); |
| booleanQuery = new BoostQuery(booleanQuery, boost); |
| |
| FieldQuery fq = new FieldQuery(booleanQuery, true, true ); |
| Set<Query> flatQueries = new HashSet<>(); |
| fq.flatten(booleanQuery, reader, flatQueries, 1f); |
| assertCollectionQueries( flatQueries, tq( boost, "A" ), tq( boost, "B" ), tq( boost, "C" ) ); |
| } |
| |
| public void testFlattenDisjunctionMaxQuery() throws Exception { |
| initBoost(); |
| Query query = dmq( tq( "A" ), tq( "B" ), pqF( "C", "D" ) ); |
| query = new BoostQuery( query, boost ); |
| FieldQuery fq = new FieldQuery( query, true, true ); |
| Set<Query> flatQueries = new HashSet<>(); |
| fq.flatten( query, reader, flatQueries, 1f ); |
| assertCollectionQueries( flatQueries, tq( boost, "A" ), tq( boost, "B" ), pqF( boost, "C", "D" ) ); |
| } |
| |
| public void testFlattenTermAndPhrase() throws Exception { |
| initBoost(); |
| BooleanQuery.Builder booleanQueryB = new BooleanQuery.Builder(); |
| booleanQueryB.add(tq("A"), Occur.MUST); |
| booleanQueryB.add(pqF("B", "C"), Occur.MUST); |
| Query booleanQuery = booleanQueryB.build(); |
| booleanQuery = new BoostQuery(booleanQuery, boost); |
| |
| FieldQuery fq = new FieldQuery(booleanQuery, true, true ); |
| Set<Query> flatQueries = new HashSet<>(); |
| fq.flatten(booleanQuery, reader, flatQueries, 1f); |
| assertCollectionQueries( flatQueries, tq( boost, "A" ), pqF( boost, "B", "C" ) ); |
| } |
| |
| public void testFlattenTermAndPhrase2gram() throws Exception { |
| BooleanQuery.Builder query = new BooleanQuery.Builder(); |
| query.add(new TermQuery(new Term(F, "AA")), Occur.MUST); |
| query.add(toPhraseQuery(analyze("BCD", F, analyzerB), F), Occur.MUST); |
| query.add(toPhraseQuery(analyze("EFGH", F, analyzerB), F), Occur.SHOULD); |
| |
| FieldQuery fq = new FieldQuery( query.build(), true, true ); |
| Set<Query> flatQueries = new HashSet<>(); |
| fq.flatten( query.build(), reader, flatQueries, 1f ); |
| assertCollectionQueries( flatQueries, tq( "AA" ), pqF( "BC", "CD" ), pqF( "EF", "FG", "GH" ) ); |
| } |
| |
| public void testFlatten1TermPhrase() throws Exception { |
| Query query = pqF( "A" ); |
| FieldQuery fq = new FieldQuery( query, true, true ); |
| Set<Query> flatQueries = new HashSet<>(); |
| fq.flatten( query, reader, flatQueries, 1f ); |
| assertCollectionQueries( flatQueries, tq( "A" ) ); |
| } |
| |
| public void testExpand() throws Exception { |
| Query dummy = pqF( "DUMMY" ); |
| FieldQuery fq = new FieldQuery( dummy, true, true ); |
| |
| // "a b","b c" => "a b","b c","a b c" |
| Set<Query> flatQueries = new HashSet<>(); |
| flatQueries.add( pqF( "a", "b" ) ); |
| flatQueries.add( pqF( "b", "c" ) ); |
| assertCollectionQueries( fq.expand( flatQueries ), |
| pqF( "a", "b" ), pqF( "b", "c" ), pqF( "a", "b", "c" ) ); |
| |
| // "a b","b c d" => "a b","b c d","a b c d" |
| flatQueries = new HashSet<>(); |
| flatQueries.add( pqF( "a", "b" ) ); |
| flatQueries.add( pqF( "b", "c", "d" ) ); |
| assertCollectionQueries( fq.expand( flatQueries ), |
| pqF( "a", "b" ), pqF( "b", "c", "d" ), pqF( "a", "b", "c", "d" ) ); |
| |
| // "a b c","b c d" => "a b c","b c d","a b c d" |
| flatQueries = new HashSet<>(); |
| flatQueries.add( pqF( "a", "b", "c" ) ); |
| flatQueries.add( pqF( "b", "c", "d" ) ); |
| assertCollectionQueries( fq.expand( flatQueries ), |
| pqF( "a", "b", "c" ), pqF( "b", "c", "d" ), pqF( "a", "b", "c", "d" ) ); |
| |
| // "a b c","c d e" => "a b c","c d e","a b c d e" |
| flatQueries = new HashSet<>(); |
| flatQueries.add( pqF( "a", "b", "c" ) ); |
| flatQueries.add( pqF( "c", "d", "e" ) ); |
| assertCollectionQueries( fq.expand( flatQueries ), |
| pqF( "a", "b", "c" ), pqF( "c", "d", "e" ), pqF( "a", "b", "c", "d", "e" ) ); |
| |
| // "a b c d","b c" => "a b c d","b c" |
| flatQueries = new HashSet<>(); |
| flatQueries.add( pqF( "a", "b", "c", "d" ) ); |
| flatQueries.add( pqF( "b", "c" ) ); |
| assertCollectionQueries( fq.expand( flatQueries ), |
| pqF( "a", "b", "c", "d" ), pqF( "b", "c" ) ); |
| |
| // "a b b","b c" => "a b b","b c","a b b c" |
| flatQueries = new HashSet<>(); |
| flatQueries.add( pqF( "a", "b", "b" ) ); |
| flatQueries.add( pqF( "b", "c" ) ); |
| assertCollectionQueries( fq.expand( flatQueries ), |
| pqF( "a", "b", "b" ), pqF( "b", "c" ), pqF( "a", "b", "b", "c" ) ); |
| |
| // "a b","b a" => "a b","b a","a b a", "b a b" |
| flatQueries = new HashSet<>(); |
| flatQueries.add( pqF( "a", "b" ) ); |
| flatQueries.add( pqF( "b", "a" ) ); |
| assertCollectionQueries( fq.expand( flatQueries ), |
| pqF( "a", "b" ), pqF( "b", "a" ), pqF( "a", "b", "a" ), pqF( "b", "a", "b" ) ); |
| |
| // "a b","a b c" => "a b","a b c" |
| flatQueries = new HashSet<>(); |
| flatQueries.add( pqF( "a", "b" ) ); |
| flatQueries.add( pqF( "a", "b", "c" ) ); |
| assertCollectionQueries( fq.expand( flatQueries ), |
| pqF( "a", "b" ), pqF( "a", "b", "c" ) ); |
| } |
| |
| public void testNoExpand() throws Exception { |
| Query dummy = pqF( "DUMMY" ); |
| FieldQuery fq = new FieldQuery( dummy, true, true ); |
| |
| // "a b","c d" => "a b","c d" |
| Set<Query> flatQueries = new HashSet<>(); |
| flatQueries.add( pqF( "a", "b" ) ); |
| flatQueries.add( pqF( "c", "d" ) ); |
| assertCollectionQueries( fq.expand( flatQueries ), |
| pqF( "a", "b" ), pqF( "c", "d" ) ); |
| |
| // "a","a b" => "a", "a b" |
| flatQueries = new HashSet<>(); |
| flatQueries.add( tq( "a" ) ); |
| flatQueries.add( pqF( "a", "b" ) ); |
| assertCollectionQueries( fq.expand( flatQueries ), |
| tq( "a" ), pqF( "a", "b" ) ); |
| |
| // "a b","b" => "a b", "b" |
| flatQueries = new HashSet<>(); |
| flatQueries.add( pqF( "a", "b" ) ); |
| flatQueries.add( tq( "b" ) ); |
| assertCollectionQueries( fq.expand( flatQueries ), |
| pqF( "a", "b" ), tq( "b" ) ); |
| |
| // "a b c","b c" => "a b c","b c" |
| flatQueries = new HashSet<>(); |
| flatQueries.add( pqF( "a", "b", "c" ) ); |
| flatQueries.add( pqF( "b", "c" ) ); |
| assertCollectionQueries( fq.expand( flatQueries ), |
| pqF( "a", "b", "c" ), pqF( "b", "c" ) ); |
| |
| // "a b","a b c" => "a b","a b c" |
| flatQueries = new HashSet<>(); |
| flatQueries.add( pqF( "a", "b" ) ); |
| flatQueries.add( pqF( "a", "b", "c" ) ); |
| assertCollectionQueries( fq.expand( flatQueries ), |
| pqF( "a", "b" ), pqF( "a", "b", "c" ) ); |
| |
| // "a b c","b d e" => "a b c","b d e" |
| flatQueries = new HashSet<>(); |
| flatQueries.add( pqF( "a", "b", "c" ) ); |
| flatQueries.add( pqF( "b", "d", "e" ) ); |
| assertCollectionQueries( fq.expand( flatQueries ), |
| pqF( "a", "b", "c" ), pqF( "b", "d", "e" ) ); |
| } |
| |
| public void testExpandNotFieldMatch() throws Exception { |
| Query dummy = pqF( "DUMMY" ); |
| FieldQuery fq = new FieldQuery( dummy, true, false ); |
| |
| // f1:"a b",f2:"b c" => f1:"a b",f2:"b c",f1:"a b c" |
| Set<Query> flatQueries = new HashSet<>(); |
| flatQueries.add( pq( F1, "a", "b" ) ); |
| flatQueries.add( pq( F2, "b", "c" ) ); |
| assertCollectionQueries( fq.expand( flatQueries ), |
| pq( F1, "a", "b" ), pq( F2, "b", "c" ), pq( F1, "a", "b", "c" ) ); |
| } |
| |
| public void testGetFieldTermMap() throws Exception { |
| Query query = tq( "a" ); |
| FieldQuery fq = new FieldQuery( query, true, true ); |
| |
| QueryPhraseMap pqm = fq.getFieldTermMap( F, "a" ); |
| assertNotNull( pqm ); |
| assertTrue( pqm.isTerminal() ); |
| |
| pqm = fq.getFieldTermMap( F, "b" ); |
| assertNull( pqm ); |
| |
| pqm = fq.getFieldTermMap( F1, "a" ); |
| assertNull( pqm ); |
| } |
| |
| public void testGetRootMap() throws Exception { |
| Query dummy = pqF( "DUMMY" ); |
| FieldQuery fq = new FieldQuery( dummy, true, true ); |
| |
| QueryPhraseMap rootMap1 = fq.getRootMap( tq( "a" ) ); |
| QueryPhraseMap rootMap2 = fq.getRootMap( tq( "a" ) ); |
| assertTrue( rootMap1 == rootMap2 ); |
| QueryPhraseMap rootMap3 = fq.getRootMap( tq( "b" ) ); |
| assertTrue( rootMap1 == rootMap3 ); |
| QueryPhraseMap rootMap4 = fq.getRootMap( tq( F1, "b" ) ); |
| assertFalse( rootMap4 == rootMap3 ); |
| } |
| |
| public void testGetRootMapNotFieldMatch() throws Exception { |
| Query dummy = pqF( "DUMMY" ); |
| FieldQuery fq = new FieldQuery( dummy, true, false ); |
| |
| QueryPhraseMap rootMap1 = fq.getRootMap( tq( "a" ) ); |
| QueryPhraseMap rootMap2 = fq.getRootMap( tq( "a" ) ); |
| assertTrue( rootMap1 == rootMap2 ); |
| QueryPhraseMap rootMap3 = fq.getRootMap( tq( "b" ) ); |
| assertTrue( rootMap1 == rootMap3 ); |
| QueryPhraseMap rootMap4 = fq.getRootMap( tq( F1, "b" ) ); |
| assertTrue( rootMap4 == rootMap3 ); |
| } |
| |
| public void testGetTermSet() throws Exception { |
| BooleanQuery.Builder query = new BooleanQuery.Builder(); |
| query.add(new TermQuery(new Term(F, "A")), Occur.MUST); |
| query.add(new TermQuery(new Term(F, "B")), Occur.MUST); |
| query.add(new TermQuery(new Term("x", "C")), Occur.SHOULD); |
| |
| BooleanQuery.Builder innerQuery = new BooleanQuery.Builder(); |
| innerQuery.add(new TermQuery(new Term(F, "D")), Occur.MUST); |
| innerQuery.add(new TermQuery(new Term(F, "E")), Occur.MUST); |
| query.add(innerQuery.build(), Occur.MUST_NOT); |
| |
| FieldQuery fq = new FieldQuery( query.build(), true, true ); |
| assertEquals( 2, fq.termSetMap.size() ); |
| Set<String> termSet = fq.getTermSet( F ); |
| assertEquals( 2, termSet.size() ); |
| assertTrue( termSet.contains( "A" ) ); |
| assertTrue( termSet.contains( "B" ) ); |
| termSet = fq.getTermSet( "x" ); |
| assertEquals( 1, termSet.size() ); |
| assertTrue( termSet.contains( "C" ) ); |
| termSet = fq.getTermSet( "y" ); |
| assertNull( termSet ); |
| } |
| |
| public void testQueryPhraseMap1Term() throws Exception { |
| Query query = tq( "a" ); |
| |
| // phraseHighlight = true, fieldMatch = true |
| FieldQuery fq = new FieldQuery( query, true, true ); |
| Map<String, QueryPhraseMap> map = fq.rootMaps; |
| assertEquals( 1, map.size() ); |
| assertNull( map.get( null ) ); |
| assertNotNull( map.get( F ) ); |
| QueryPhraseMap qpm = map.get( F ); |
| assertEquals( 1, qpm.subMap.size() ); |
| assertTrue( qpm.subMap.get( "a" ) != null ); |
| assertTrue( qpm.subMap.get( "a" ).terminal ); |
| assertEquals( 1F, qpm.subMap.get( "a" ).boost, 0); |
| |
| // phraseHighlight = true, fieldMatch = false |
| fq = new FieldQuery( query, true, false ); |
| map = fq.rootMaps; |
| assertEquals( 1, map.size() ); |
| assertNull( map.get( F ) ); |
| assertNotNull( map.get( null ) ); |
| qpm = map.get( null ); |
| assertEquals( 1, qpm.subMap.size() ); |
| assertTrue( qpm.subMap.get( "a" ) != null ); |
| assertTrue( qpm.subMap.get( "a" ).terminal ); |
| assertEquals( 1F, qpm.subMap.get( "a" ).boost, 0); |
| |
| // phraseHighlight = false, fieldMatch = true |
| fq = new FieldQuery( query, false, true ); |
| map = fq.rootMaps; |
| assertEquals( 1, map.size() ); |
| assertNull( map.get( null ) ); |
| assertNotNull( map.get( F ) ); |
| qpm = map.get( F ); |
| assertEquals( 1, qpm.subMap.size() ); |
| assertTrue( qpm.subMap.get( "a" ) != null ); |
| assertTrue( qpm.subMap.get( "a" ).terminal ); |
| assertEquals( 1F, qpm.subMap.get( "a" ).boost, 0); |
| |
| // phraseHighlight = false, fieldMatch = false |
| fq = new FieldQuery( query, false, false ); |
| map = fq.rootMaps; |
| assertEquals( 1, map.size() ); |
| assertNull( map.get( F ) ); |
| assertNotNull( map.get( null ) ); |
| qpm = map.get( null ); |
| assertEquals( 1, qpm.subMap.size() ); |
| assertTrue( qpm.subMap.get( "a" ) != null ); |
| assertTrue( qpm.subMap.get( "a" ).terminal ); |
| assertEquals( 1F, qpm.subMap.get( "a" ).boost, 0); |
| |
| // boost != 1 |
| query = tq( 2, "a" ); |
| fq = new FieldQuery( query, true, true ); |
| map = fq.rootMaps; |
| qpm = map.get( F ); |
| assertEquals( 2F, qpm.subMap.get( "a" ).boost, 0); |
| } |
| |
| public void testQueryPhraseMap1Phrase() throws Exception { |
| Query query = pqF( "a", "b" ); |
| |
| // phraseHighlight = true, fieldMatch = true |
| FieldQuery fq = new FieldQuery( query, true, true ); |
| Map<String, QueryPhraseMap> map = fq.rootMaps; |
| assertEquals( 1, map.size() ); |
| assertNull( map.get( null ) ); |
| assertNotNull( map.get( F ) ); |
| QueryPhraseMap qpm = map.get( F ); |
| assertEquals( 1, qpm.subMap.size() ); |
| assertNotNull( qpm.subMap.get( "a" ) ); |
| QueryPhraseMap qpm2 = qpm.subMap.get( "a" ); |
| assertFalse( qpm2.terminal ); |
| assertEquals( 1, qpm2.subMap.size() ); |
| assertNotNull( qpm2.subMap.get( "b" ) ); |
| QueryPhraseMap qpm3 = qpm2.subMap.get( "b" ); |
| assertTrue( qpm3.terminal ); |
| assertEquals( 1F, qpm3.boost, 0); |
| |
| // phraseHighlight = true, fieldMatch = false |
| fq = new FieldQuery( query, true, false ); |
| map = fq.rootMaps; |
| assertEquals( 1, map.size() ); |
| assertNull( map.get( F ) ); |
| assertNotNull( map.get( null ) ); |
| qpm = map.get( null ); |
| assertEquals( 1, qpm.subMap.size() ); |
| assertNotNull( qpm.subMap.get( "a" ) ); |
| qpm2 = qpm.subMap.get( "a" ); |
| assertFalse( qpm2.terminal ); |
| assertEquals( 1, qpm2.subMap.size() ); |
| assertNotNull( qpm2.subMap.get( "b" ) ); |
| qpm3 = qpm2.subMap.get( "b" ); |
| assertTrue( qpm3.terminal ); |
| assertEquals( 1F, qpm3.boost, 0); |
| |
| // phraseHighlight = false, fieldMatch = true |
| fq = new FieldQuery( query, false, true ); |
| map = fq.rootMaps; |
| assertEquals( 1, map.size() ); |
| assertNull( map.get( null ) ); |
| assertNotNull( map.get( F ) ); |
| qpm = map.get( F ); |
| assertEquals( 2, qpm.subMap.size() ); |
| assertNotNull( qpm.subMap.get( "a" ) ); |
| qpm2 = qpm.subMap.get( "a" ); |
| assertTrue( qpm2.terminal ); |
| assertEquals( 1F, qpm2.boost, 0); |
| assertEquals( 1, qpm2.subMap.size() ); |
| assertNotNull( qpm2.subMap.get( "b" ) ); |
| qpm3 = qpm2.subMap.get( "b" ); |
| assertTrue( qpm3.terminal ); |
| assertEquals( 1F, qpm3.boost, 0); |
| |
| assertNotNull( qpm.subMap.get( "b" ) ); |
| qpm2 = qpm.subMap.get( "b" ); |
| assertTrue( qpm2.terminal ); |
| assertEquals( 1F, qpm2.boost, 0); |
| |
| // phraseHighlight = false, fieldMatch = false |
| fq = new FieldQuery( query, false, false ); |
| map = fq.rootMaps; |
| assertEquals( 1, map.size() ); |
| assertNull( map.get( F ) ); |
| assertNotNull( map.get( null ) ); |
| qpm = map.get( null ); |
| assertEquals( 2, qpm.subMap.size() ); |
| assertNotNull( qpm.subMap.get( "a" ) ); |
| qpm2 = qpm.subMap.get( "a" ); |
| assertTrue( qpm2.terminal ); |
| assertEquals( 1F, qpm2.boost, 0); |
| assertEquals( 1, qpm2.subMap.size() ); |
| assertNotNull( qpm2.subMap.get( "b" ) ); |
| qpm3 = qpm2.subMap.get( "b" ); |
| assertTrue( qpm3.terminal ); |
| assertEquals( 1F, qpm3.boost, 0); |
| |
| assertNotNull( qpm.subMap.get( "b" ) ); |
| qpm2 = qpm.subMap.get( "b" ); |
| assertTrue( qpm2.terminal ); |
| assertEquals( 1F, qpm2.boost, 0); |
| |
| // boost != 1 |
| query = pqF( 2, "a", "b" ); |
| // phraseHighlight = false, fieldMatch = false |
| fq = new FieldQuery( query, false, false ); |
| map = fq.rootMaps; |
| qpm = map.get( null ); |
| qpm2 = qpm.subMap.get( "a" ); |
| assertEquals( 2F, qpm2.boost, 0); |
| qpm3 = qpm2.subMap.get( "b" ); |
| assertEquals( 2F, qpm3.boost, 0); |
| qpm2 = qpm.subMap.get( "b" ); |
| assertEquals( 2F, qpm2.boost, 0); |
| } |
| |
| public void testQueryPhraseMap1PhraseAnother() throws Exception { |
| Query query = pqF( "search", "engines" ); |
| |
| // phraseHighlight = true, fieldMatch = true |
| FieldQuery fq = new FieldQuery( query, true, true ); |
| Map<String, QueryPhraseMap> map = fq.rootMaps; |
| assertEquals( 1, map.size() ); |
| assertNull( map.get( null ) ); |
| assertNotNull( map.get( F ) ); |
| QueryPhraseMap qpm = map.get( F ); |
| assertEquals( 1, qpm.subMap.size() ); |
| assertNotNull( qpm.subMap.get( "search" ) ); |
| QueryPhraseMap qpm2 = qpm.subMap.get( "search" ); |
| assertFalse( qpm2.terminal ); |
| assertEquals( 1, qpm2.subMap.size() ); |
| assertNotNull( qpm2.subMap.get( "engines" ) ); |
| QueryPhraseMap qpm3 = qpm2.subMap.get( "engines" ); |
| assertTrue( qpm3.terminal ); |
| assertEquals( 1F, qpm3.boost, 0); |
| } |
| |
| public void testQueryPhraseMap2Phrases() throws Exception { |
| BooleanQuery.Builder query = new BooleanQuery.Builder(); |
| query.add( pqF( "a", "b" ), Occur.SHOULD ); |
| query.add( pqF( 2, "c", "d" ), Occur.SHOULD ); |
| |
| // phraseHighlight = true, fieldMatch = true |
| FieldQuery fq = new FieldQuery( query.build(), true, true ); |
| Map<String, QueryPhraseMap> map = fq.rootMaps; |
| assertEquals( 1, map.size() ); |
| assertNull( map.get( null ) ); |
| assertNotNull( map.get( F ) ); |
| QueryPhraseMap qpm = map.get( F ); |
| assertEquals( 2, qpm.subMap.size() ); |
| |
| // "a b" |
| assertNotNull( qpm.subMap.get( "a" ) ); |
| QueryPhraseMap qpm2 = qpm.subMap.get( "a" ); |
| assertFalse( qpm2.terminal ); |
| assertEquals( 1, qpm2.subMap.size() ); |
| assertNotNull( qpm2.subMap.get( "b" ) ); |
| QueryPhraseMap qpm3 = qpm2.subMap.get( "b" ); |
| assertTrue( qpm3.terminal ); |
| assertEquals( 1F, qpm3.boost, 0); |
| |
| // "c d"^2 |
| assertNotNull( qpm.subMap.get( "c" ) ); |
| qpm2 = qpm.subMap.get( "c" ); |
| assertFalse( qpm2.terminal ); |
| assertEquals( 1, qpm2.subMap.size() ); |
| assertNotNull( qpm2.subMap.get( "d" ) ); |
| qpm3 = qpm2.subMap.get( "d" ); |
| assertTrue( qpm3.terminal ); |
| assertEquals( 2F, qpm3.boost, 0); |
| } |
| |
| public void testQueryPhraseMap2PhrasesFields() throws Exception { |
| BooleanQuery.Builder query = new BooleanQuery.Builder(); |
| query.add( pq( F1, "a", "b" ), Occur.SHOULD ); |
| query.add( pq( 2F, F2, "c", "d" ), Occur.SHOULD ); |
| |
| // phraseHighlight = true, fieldMatch = true |
| FieldQuery fq = new FieldQuery( query.build(), true, true ); |
| Map<String, QueryPhraseMap> map = fq.rootMaps; |
| assertEquals( 2, map.size() ); |
| assertNull( map.get( null ) ); |
| |
| // "a b" |
| assertNotNull( map.get( F1 ) ); |
| QueryPhraseMap qpm = map.get( F1 ); |
| assertEquals( 1, qpm.subMap.size() ); |
| assertNotNull( qpm.subMap.get( "a" ) ); |
| QueryPhraseMap qpm2 = qpm.subMap.get( "a" ); |
| assertFalse( qpm2.terminal ); |
| assertEquals( 1, qpm2.subMap.size() ); |
| assertNotNull( qpm2.subMap.get( "b" ) ); |
| QueryPhraseMap qpm3 = qpm2.subMap.get( "b" ); |
| assertTrue( qpm3.terminal ); |
| assertEquals( 1F, qpm3.boost, 0); |
| |
| // "c d"^2 |
| assertNotNull( map.get( F2 ) ); |
| qpm = map.get( F2 ); |
| assertEquals( 1, qpm.subMap.size() ); |
| assertNotNull( qpm.subMap.get( "c" ) ); |
| qpm2 = qpm.subMap.get( "c" ); |
| assertFalse( qpm2.terminal ); |
| assertEquals( 1, qpm2.subMap.size() ); |
| assertNotNull( qpm2.subMap.get( "d" ) ); |
| qpm3 = qpm2.subMap.get( "d" ); |
| assertTrue( qpm3.terminal ); |
| assertEquals( 2F, qpm3.boost, 0); |
| |
| // phraseHighlight = true, fieldMatch = false |
| fq = new FieldQuery( query.build(), true, false ); |
| map = fq.rootMaps; |
| assertEquals( 1, map.size() ); |
| assertNull( map.get( F1 ) ); |
| assertNull( map.get( F2 ) ); |
| assertNotNull( map.get( null ) ); |
| qpm = map.get( null ); |
| assertEquals( 2, qpm.subMap.size() ); |
| |
| // "a b" |
| assertNotNull( qpm.subMap.get( "a" ) ); |
| qpm2 = qpm.subMap.get( "a" ); |
| assertFalse( qpm2.terminal ); |
| assertEquals( 1, qpm2.subMap.size() ); |
| assertNotNull( qpm2.subMap.get( "b" ) ); |
| qpm3 = qpm2.subMap.get( "b" ); |
| assertTrue( qpm3.terminal ); |
| assertEquals( 1F, qpm3.boost, 0); |
| |
| // "c d"^2 |
| assertNotNull( qpm.subMap.get( "c" ) ); |
| qpm2 = qpm.subMap.get( "c" ); |
| assertFalse( qpm2.terminal ); |
| assertEquals( 1, qpm2.subMap.size() ); |
| assertNotNull( qpm2.subMap.get( "d" ) ); |
| qpm3 = qpm2.subMap.get( "d" ); |
| assertTrue( qpm3.terminal ); |
| assertEquals( 2F, qpm3.boost, 0); |
| } |
| |
| /* |
| * <t>...terminal |
| * |
| * a-b-c-<t> |
| * +-d-<t> |
| * b-c-d-<t> |
| * +-d-<t> |
| */ |
| public void testQueryPhraseMapOverlapPhrases() throws Exception { |
| BooleanQuery.Builder query = new BooleanQuery.Builder(); |
| query.add( pqF( "a", "b", "c" ), Occur.SHOULD ); |
| query.add( pqF( 2, "b", "c", "d" ), Occur.SHOULD ); |
| query.add( pqF( 3, "b", "d" ), Occur.SHOULD ); |
| |
| // phraseHighlight = true, fieldMatch = true |
| FieldQuery fq = new FieldQuery( query.build(), true, true ); |
| Map<String, QueryPhraseMap> map = fq.rootMaps; |
| assertEquals( 1, map.size() ); |
| assertNull( map.get( null ) ); |
| assertNotNull( map.get( F ) ); |
| QueryPhraseMap qpm = map.get( F ); |
| assertEquals( 2, qpm.subMap.size() ); |
| |
| // "a b c" |
| assertNotNull( qpm.subMap.get( "a" ) ); |
| QueryPhraseMap qpm2 = qpm.subMap.get( "a" ); |
| assertFalse( qpm2.terminal ); |
| assertEquals( 1, qpm2.subMap.size() ); |
| assertNotNull( qpm2.subMap.get( "b" ) ); |
| QueryPhraseMap qpm3 = qpm2.subMap.get( "b" ); |
| assertFalse( qpm3.terminal ); |
| assertEquals( 1, qpm3.subMap.size() ); |
| assertNotNull( qpm3.subMap.get( "c" ) ); |
| QueryPhraseMap qpm4 = qpm3.subMap.get( "c" ); |
| assertTrue( qpm4.terminal ); |
| assertEquals( 1F, qpm4.boost, 0); |
| assertNotNull( qpm4.subMap.get( "d" ) ); |
| QueryPhraseMap qpm5 = qpm4.subMap.get( "d" ); |
| assertTrue( qpm5.terminal ); |
| assertEquals( 1F, qpm5.boost, 0); |
| |
| // "b c d"^2, "b d"^3 |
| assertNotNull( qpm.subMap.get( "b" ) ); |
| qpm2 = qpm.subMap.get( "b" ); |
| assertFalse( qpm2.terminal ); |
| assertEquals( 2, qpm2.subMap.size() ); |
| assertNotNull( qpm2.subMap.get( "c" ) ); |
| qpm3 = qpm2.subMap.get( "c" ); |
| assertFalse( qpm3.terminal ); |
| assertEquals( 1, qpm3.subMap.size() ); |
| assertNotNull( qpm3.subMap.get( "d" ) ); |
| qpm4 = qpm3.subMap.get( "d" ); |
| assertTrue( qpm4.terminal ); |
| assertEquals( 2F, qpm4.boost, 0); |
| assertNotNull( qpm2.subMap.get( "d" ) ); |
| qpm3 = qpm2.subMap.get( "d" ); |
| assertTrue( qpm3.terminal ); |
| assertEquals( 3F, qpm3.boost, 0); |
| } |
| |
| /* |
| * <t>...terminal |
| * |
| * a-b-<t> |
| * +-c-<t> |
| */ |
| public void testQueryPhraseMapOverlapPhrases2() throws Exception { |
| BooleanQuery.Builder query = new BooleanQuery.Builder(); |
| query.add( pqF( "a", "b" ), Occur.SHOULD ); |
| query.add( pqF( 2, "a", "b", "c" ), Occur.SHOULD ); |
| |
| // phraseHighlight = true, fieldMatch = true |
| FieldQuery fq = new FieldQuery( query.build(), true, true ); |
| Map<String, QueryPhraseMap> map = fq.rootMaps; |
| assertEquals( 1, map.size() ); |
| assertNull( map.get( null ) ); |
| assertNotNull( map.get( F ) ); |
| QueryPhraseMap qpm = map.get( F ); |
| assertEquals( 1, qpm.subMap.size() ); |
| |
| // "a b" |
| assertNotNull( qpm.subMap.get( "a" ) ); |
| QueryPhraseMap qpm2 = qpm.subMap.get( "a" ); |
| assertFalse( qpm2.terminal ); |
| assertEquals( 1, qpm2.subMap.size() ); |
| assertNotNull( qpm2.subMap.get( "b" ) ); |
| QueryPhraseMap qpm3 = qpm2.subMap.get( "b" ); |
| assertTrue( qpm3.terminal ); |
| assertEquals( 1F, qpm3.boost, 0); |
| |
| // "a b c"^2 |
| assertEquals( 1, qpm3.subMap.size() ); |
| assertNotNull( qpm3.subMap.get( "c" ) ); |
| QueryPhraseMap qpm4 = qpm3.subMap.get( "c" ); |
| assertTrue( qpm4.terminal ); |
| assertEquals( 2F, qpm4.boost, 0); |
| } |
| |
| /* |
| * <t>...terminal |
| * |
| * a-a-a-<t> |
| * +-a-<t> |
| * +-a-<t> |
| * +-a-<t> |
| */ |
| public void testQueryPhraseMapOverlapPhrases3() throws Exception { |
| BooleanQuery.Builder query = new BooleanQuery.Builder(); |
| query.add( pqF( "a", "a", "a", "a" ), Occur.SHOULD ); |
| query.add( pqF( 2, "a", "a", "a" ), Occur.SHOULD ); |
| |
| // phraseHighlight = true, fieldMatch = true |
| FieldQuery fq = new FieldQuery( query.build(), true, true ); |
| Map<String, QueryPhraseMap> map = fq.rootMaps; |
| assertEquals( 1, map.size() ); |
| assertNull( map.get( null ) ); |
| assertNotNull( map.get( F ) ); |
| QueryPhraseMap qpm = map.get( F ); |
| assertEquals( 1, qpm.subMap.size() ); |
| |
| // "a a a" |
| assertNotNull( qpm.subMap.get( "a" ) ); |
| QueryPhraseMap qpm2 = qpm.subMap.get( "a" ); |
| assertFalse( qpm2.terminal ); |
| assertEquals( 1, qpm2.subMap.size() ); |
| assertNotNull( qpm2.subMap.get( "a" ) ); |
| QueryPhraseMap qpm3 = qpm2.subMap.get( "a" ); |
| assertFalse( qpm3.terminal ); |
| assertEquals( 1, qpm3.subMap.size() ); |
| assertNotNull( qpm3.subMap.get( "a" ) ); |
| QueryPhraseMap qpm4 = qpm3.subMap.get( "a" ); |
| assertTrue( qpm4.terminal ); |
| |
| // "a a a a" |
| assertEquals( 1, qpm4.subMap.size() ); |
| assertNotNull( qpm4.subMap.get( "a" ) ); |
| QueryPhraseMap qpm5 = qpm4.subMap.get( "a" ); |
| assertTrue( qpm5.terminal ); |
| |
| // "a a a a a" |
| assertEquals( 1, qpm5.subMap.size() ); |
| assertNotNull( qpm5.subMap.get( "a" ) ); |
| QueryPhraseMap qpm6 = qpm5.subMap.get( "a" ); |
| assertTrue( qpm6.terminal ); |
| |
| // "a a a a a a" |
| assertEquals( 1, qpm6.subMap.size() ); |
| assertNotNull( qpm6.subMap.get( "a" ) ); |
| QueryPhraseMap qpm7 = qpm6.subMap.get( "a" ); |
| assertTrue( qpm7.terminal ); |
| } |
| |
| public void testQueryPhraseMapOverlap2gram() throws Exception { |
| BooleanQuery.Builder query = new BooleanQuery.Builder(); |
| query.add(toPhraseQuery(analyze("abc", F, analyzerB), F), Occur.MUST); |
| query.add(toPhraseQuery(analyze("bcd", F, analyzerB), F), Occur.MUST); |
| |
| // phraseHighlight = true, fieldMatch = true |
| FieldQuery fq = new FieldQuery( query.build(), true, true ); |
| Map<String, QueryPhraseMap> map = fq.rootMaps; |
| assertEquals( 1, map.size() ); |
| assertNull( map.get( null ) ); |
| assertNotNull( map.get( F ) ); |
| QueryPhraseMap qpm = map.get( F ); |
| assertEquals( 2, qpm.subMap.size() ); |
| |
| // "ab bc" |
| assertNotNull( qpm.subMap.get( "ab" ) ); |
| QueryPhraseMap qpm2 = qpm.subMap.get( "ab" ); |
| assertFalse( qpm2.terminal ); |
| assertEquals( 1, qpm2.subMap.size() ); |
| assertNotNull( qpm2.subMap.get( "bc" ) ); |
| QueryPhraseMap qpm3 = qpm2.subMap.get( "bc" ); |
| assertTrue( qpm3.terminal ); |
| assertEquals( 1F, qpm3.boost, 0); |
| |
| // "ab bc cd" |
| assertEquals( 1, qpm3.subMap.size() ); |
| assertNotNull( qpm3.subMap.get( "cd" ) ); |
| QueryPhraseMap qpm4 = qpm3.subMap.get( "cd" ); |
| assertTrue( qpm4.terminal ); |
| assertEquals( 1F, qpm4.boost, 0); |
| |
| // "bc cd" |
| assertNotNull( qpm.subMap.get( "bc" ) ); |
| qpm2 = qpm.subMap.get( "bc" ); |
| assertFalse( qpm2.terminal ); |
| assertEquals( 1, qpm2.subMap.size() ); |
| assertNotNull( qpm2.subMap.get( "cd" ) ); |
| qpm3 = qpm2.subMap.get( "cd" ); |
| assertTrue( qpm3.terminal ); |
| assertEquals( 1F, qpm3.boost, 0); |
| |
| // phraseHighlight = false, fieldMatch = true |
| fq = new FieldQuery( query.build(), false, true ); |
| map = fq.rootMaps; |
| assertEquals( 1, map.size() ); |
| assertNull( map.get( null ) ); |
| assertNotNull( map.get( F ) ); |
| qpm = map.get( F ); |
| assertEquals( 3, qpm.subMap.size() ); |
| |
| // "ab bc" |
| assertNotNull( qpm.subMap.get( "ab" ) ); |
| qpm2 = qpm.subMap.get( "ab" ); |
| assertTrue( qpm2.terminal ); |
| assertEquals( 1F, qpm2.boost, 0); |
| assertEquals( 1, qpm2.subMap.size() ); |
| assertNotNull( qpm2.subMap.get( "bc" ) ); |
| qpm3 = qpm2.subMap.get( "bc" ); |
| assertTrue( qpm3.terminal ); |
| assertEquals( 1F, qpm3.boost, 0); |
| |
| // "ab bc cd" |
| assertEquals( 1, qpm3.subMap.size() ); |
| assertNotNull( qpm3.subMap.get( "cd" ) ); |
| qpm4 = qpm3.subMap.get( "cd" ); |
| assertTrue( qpm4.terminal ); |
| assertEquals( 1F, qpm4.boost, 0); |
| |
| // "bc cd" |
| assertNotNull( qpm.subMap.get( "bc" ) ); |
| qpm2 = qpm.subMap.get( "bc" ); |
| assertTrue( qpm2.terminal ); |
| assertEquals( 1F, qpm2.boost, 0); |
| assertEquals( 1, qpm2.subMap.size() ); |
| assertNotNull( qpm2.subMap.get( "cd" ) ); |
| qpm3 = qpm2.subMap.get( "cd" ); |
| assertTrue( qpm3.terminal ); |
| assertEquals( 1F, qpm3.boost, 0); |
| |
| // "cd" |
| assertNotNull( qpm.subMap.get( "cd" ) ); |
| qpm2 = qpm.subMap.get( "cd" ); |
| assertTrue( qpm2.terminal ); |
| assertEquals( 1F, qpm2.boost, 0); |
| assertEquals( 0, qpm2.subMap.size() ); |
| } |
| |
| public void testSearchPhrase() throws Exception { |
| Query query = pqF( "a", "b", "c" ); |
| |
| // phraseHighlight = true, fieldMatch = true |
| FieldQuery fq = new FieldQuery( query, true, true ); |
| |
| // "a" |
| List<TermInfo> phraseCandidate = new ArrayList<>(); |
| phraseCandidate.add( new TermInfo( "a", 0, 1, 0, 1 ) ); |
| assertNull( fq.searchPhrase( F, phraseCandidate ) ); |
| // "a b" |
| phraseCandidate.add( new TermInfo( "b", 2, 3, 1, 1 ) ); |
| assertNull( fq.searchPhrase( F, phraseCandidate ) ); |
| // "a b c" |
| phraseCandidate.add( new TermInfo( "c", 4, 5, 2, 1 ) ); |
| assertNotNull( fq.searchPhrase( F, phraseCandidate ) ); |
| assertNull( fq.searchPhrase( "x", phraseCandidate ) ); |
| |
| // phraseHighlight = true, fieldMatch = false |
| fq = new FieldQuery( query, true, false ); |
| |
| // "a b c" |
| assertNotNull( fq.searchPhrase( F, phraseCandidate ) ); |
| assertNotNull( fq.searchPhrase( "x", phraseCandidate ) ); |
| |
| // phraseHighlight = false, fieldMatch = true |
| fq = new FieldQuery( query, false, true ); |
| |
| // "a" |
| phraseCandidate.clear(); |
| phraseCandidate.add( new TermInfo( "a", 0, 1, 0, 1 ) ); |
| assertNotNull( fq.searchPhrase( F, phraseCandidate ) ); |
| // "a b" |
| phraseCandidate.add( new TermInfo( "b", 2, 3, 1, 1 ) ); |
| assertNull( fq.searchPhrase( F, phraseCandidate ) ); |
| // "a b c" |
| phraseCandidate.add( new TermInfo( "c", 4, 5, 2, 1 ) ); |
| assertNotNull( fq.searchPhrase( F, phraseCandidate ) ); |
| assertNull( fq.searchPhrase( "x", phraseCandidate ) ); |
| } |
| |
| public void testSearchPhraseSlop() throws Exception { |
| // "a b c"~0 |
| Query query = pqF( "a", "b", "c" ); |
| |
| // phraseHighlight = true, fieldMatch = true |
| FieldQuery fq = new FieldQuery( query, true, true ); |
| |
| // "a b c" w/ position-gap = 2 |
| List<TermInfo> phraseCandidate = new ArrayList<>(); |
| phraseCandidate.add( new TermInfo( "a", 0, 1, 0, 1 ) ); |
| phraseCandidate.add( new TermInfo( "b", 2, 3, 2, 1 ) ); |
| phraseCandidate.add( new TermInfo( "c", 4, 5, 4, 1 ) ); |
| assertNull( fq.searchPhrase( F, phraseCandidate ) ); |
| |
| // "a b c"~1 |
| query = pqF( 1F, 1, "a", "b", "c" ); |
| |
| // phraseHighlight = true, fieldMatch = true |
| fq = new FieldQuery( query, true, true ); |
| |
| // "a b c" w/ position-gap = 2 |
| assertNotNull( fq.searchPhrase( F, phraseCandidate ) ); |
| |
| // "a b c" w/ position-gap = 3 |
| phraseCandidate.clear(); |
| phraseCandidate.add( new TermInfo( "a", 0, 1, 0, 1 ) ); |
| phraseCandidate.add( new TermInfo( "b", 2, 3, 3, 1 ) ); |
| phraseCandidate.add( new TermInfo( "c", 4, 5, 6, 1 ) ); |
| assertNull( fq.searchPhrase( F, phraseCandidate ) ); |
| } |
| |
| public void testHighlightQuery() throws Exception { |
| makeIndexStrMV(); |
| defgMultiTermQueryTest(new WildcardQuery(new Term(F, "d*g"))); |
| } |
| |
| public void testPrefixQuery() throws Exception { |
| makeIndexStrMV(); |
| defgMultiTermQueryTest(new PrefixQuery(new Term(F, "de"))); |
| } |
| |
| public void testRegexpQuery() throws Exception { |
| makeIndexStrMV(); |
| Term term = new Term(F, "d[a-z].g"); |
| defgMultiTermQueryTest(new RegexpQuery(term)); |
| } |
| |
| public void testRangeQuery() throws Exception { |
| makeIndexStrMV(); |
| defgMultiTermQueryTest(new TermRangeQuery (F, new BytesRef("d"), new BytesRef("e"), true, true)); |
| } |
| |
| private void defgMultiTermQueryTest(Query query) throws IOException { |
| FieldQuery fq = new FieldQuery( query, reader, true, true ); |
| QueryPhraseMap qpm = fq.getFieldTermMap(F, "defg"); |
| assertNotNull (qpm); |
| assertNull (fq.getFieldTermMap(F, "dog")); |
| List<TermInfo> phraseCandidate = new ArrayList<>(); |
| phraseCandidate.add( new TermInfo( "defg", 0, 12, 0, 1 ) ); |
| assertNotNull (fq.searchPhrase(F, phraseCandidate)); |
| } |
| |
| public void testStopRewrite() throws Exception { |
| Query q = new Query() { |
| |
| @Override |
| public String toString(String field) { |
| return "DummyQuery"; |
| } |
| |
| @Override |
| public void visit(QueryVisitor visitor) { |
| |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| throw new AssertionError(); |
| } |
| |
| @Override |
| public int hashCode() { |
| throw new AssertionError(); |
| } |
| }; |
| make1d1fIndex( "a" ); |
| assertNotNull(reader); |
| new FieldQuery(q, reader, true, true ); |
| } |
| |
| public void testFlattenConstantScoreQuery() throws Exception { |
| initBoost(); |
| Query query = new ConstantScoreQuery(pqF( "A" )); |
| query = new BoostQuery(query, boost); |
| FieldQuery fq = new FieldQuery( query, true, true ); |
| Set<Query> flatQueries = new HashSet<>(); |
| fq.flatten( query, reader, flatQueries, 1f ); |
| assertCollectionQueries( flatQueries, tq( boost, "A" ) ); |
| } |
| } |