/*
* Hibernate Search, full-text search for your domain model
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.search.test.query.engine;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.IntField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.DisjunctionMaxQuery;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.MultiPhraseQuery;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
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.store.Directory;
import org.apache.lucene.store.RAMDirectory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.hibernate.search.query.engine.impl.FieldNameCollector;
import static org.junit.Assert.fail;
/**
* @author Hardy Ferentschik
*/
public class FieldNameCollectorTest {
DirectoryReader indexReader;
@Before
public void setUp() throws Exception {
Directory directory = new RAMDirectory();
indexTestDocuments( directory );
indexReader = DirectoryReader.open( directory );
}
@After
public void tearDown() throws Exception {
indexReader.close();
}
@Test
public void testExtractFieldNameFromTermQuery() {
TermQuery query = new TermQuery( new Term( "stringField", "foobar" ) );
assertFieldNames( query, FieldType.STRING, "stringField" );
}
@Test
public void testExtractFieldNameFromWildcardQuery() {
WildcardQuery query = new WildcardQuery( new Term( "stringField", "foo*" ) );
assertFieldNames( query, FieldType.STRING, "stringField" );
}
@Test
public void testExtractFieldNameFromFuzzyQuery() {
FuzzyQuery query = new FuzzyQuery( new Term( "stringField", "foo*" ) );
assertFieldNames( query, FieldType.STRING, "stringField" );
}
@Test
public void testExtractFieldNameFromRegexpQuery() {
RegexpQuery query = new RegexpQuery( new Term( "stringField", ".foo?" ) );
assertFieldNames( query, FieldType.STRING, "stringField" );
}
@Test
public void testExtractFieldNameFromPrefixQuery() {
PrefixQuery query = new PrefixQuery( new Term( "stringField", "foo*" ) );
assertFieldNames( query, FieldType.STRING, "stringField" );
}
@Test
public void testExtractFieldNameFromMultiPhraseQuery() {
MultiPhraseQuery phraseQuery = new MultiPhraseQuery();
phraseQuery.add( new Term( "stringField1", "hello world" ) );
assertFieldNames( phraseQuery, FieldType.STRING, "stringField1" );
}
@Test
public void testExtractFieldNameFromPhraseQuery() {
PhraseQuery phraseQuery = new PhraseQuery();
phraseQuery.add( new Term( "stringField", "hello world" ) );
assertFieldNames( phraseQuery, FieldType.STRING, "stringField" );
}
@Test
public void testExtractFieldNameFromTermRangeQuery() {
TermRangeQuery query = TermRangeQuery.newStringRange( "stringField", "A", "Z", true, true );
assertFieldNames( query, FieldType.STRING, "stringField" );
}
@Test
public void testExtractFieldNameFromNumericRangeQuery() {
NumericRangeQuery query = NumericRangeQuery.newIntRange( "intField", 0, 0, true, true );
assertFieldNames( query, FieldType.NUMBER, "intField" );
}
@Test
public void testBooleanQuery() {
BooleanQuery.Builder booleanQueryBuilder = new BooleanQuery.Builder();
TermQuery termQuery = new TermQuery( new Term( "stringField", "foobar" ) );
booleanQueryBuilder.add( termQuery, BooleanClause.Occur.MUST );
NumericRangeQuery numericRangeQuery = NumericRangeQuery.newIntRange( "intField", 0, 0, true, true );
booleanQueryBuilder.add( numericRangeQuery, BooleanClause.Occur.SHOULD );
BooleanQuery booleanQuery = booleanQueryBuilder.build();
assertFieldNames( booleanQuery, FieldType.NUMBER, "intField" );
assertFieldNames( booleanQuery, FieldType.STRING, "stringField" );
}
@Test
public void testNestedBooleanQuery() {
BooleanQuery.Builder booleanQueryBuilder = new BooleanQuery.Builder();
TermQuery termQuery = new TermQuery( new Term( "stringField", "foobar" ) );
booleanQueryBuilder.add( termQuery, BooleanClause.Occur.MUST );
BooleanQuery.Builder nestedBuilder = new BooleanQuery.Builder();
NumericRangeQuery numericRangeQuery = NumericRangeQuery.newIntRange( "intField", 0, 0, true, true );
nestedBuilder.add( numericRangeQuery, BooleanClause.Occur.SHOULD );
BooleanQuery nestedBooleanQuery = nestedBuilder.build();
booleanQueryBuilder.add( nestedBooleanQuery, BooleanClause.Occur.MUST );
BooleanQuery booleanQuery = booleanQueryBuilder.build();
assertFieldNames( booleanQuery, FieldType.NUMBER, "intField" );
assertFieldNames( booleanQuery, FieldType.STRING, "stringField" );
}
@Test
public void testDisjunctionMaxQuery() {
DisjunctionMaxQuery disjunctionMaxQuery = new DisjunctionMaxQuery( 0.0f );
TermQuery termQuery = new TermQuery( new Term( "stringField", "foobar" ) );
disjunctionMaxQuery.add( termQuery );
NumericRangeQuery numericRangeQuery = NumericRangeQuery.newIntRange( "intField", 0, 0, true, true );
disjunctionMaxQuery.add( numericRangeQuery );
assertFieldNames( disjunctionMaxQuery, FieldType.NUMBER, "intField" );
assertFieldNames( disjunctionMaxQuery, FieldType.STRING, "stringField" );
}
private void assertFieldNames(Query query, FieldType fieldType, String... expectedFields) {
FieldNameCollector.FieldCollection fieldCollection = FieldNameCollector.extractFieldNames( query );
Set<String> actualFieldNames = new HashSet<>();
if ( FieldType.STRING.equals( fieldType ) ) {
actualFieldNames.addAll( fieldCollection.getStringFieldNames() );
}
else {
actualFieldNames.addAll( fieldCollection.getNumericFieldNames() );
}
for ( String expectedFieldName : expectedFields ) {
if ( !actualFieldNames.contains( expectedFieldName ) ) {
fail( "The expected field name " + expectedFieldName + " was not found in the actual field names: " + actualFieldNames );
}
actualFieldNames.remove( expectedFieldName );
}
if ( !actualFieldNames.isEmpty() ) {
fail( "There were field names which were unexpected: " + actualFieldNames );
}
}
private void indexTestDocuments(Directory directory) throws IOException {
IndexWriterConfig indexWriterConfig = new IndexWriterConfig( new StandardAnalyzer() );
indexWriterConfig.setOpenMode( IndexWriterConfig.OpenMode.CREATE );
IndexWriter indexWriter = new IndexWriter( directory, indexWriterConfig );
Document document = new Document();
document.add( new StringField( "stringField", "test", Field.Store.NO ) );
document.add( new IntField( "intField", 0, Field.Store.NO ) );
indexWriter.addDocument( document );
indexWriter.commit();
indexWriter.close();
}
enum FieldType {
STRING,
NUMBER
}
}