[hibernate-commits] Hibernate SVN: r19013 - in search/trunk/hibernate-search/src: main/java/org/hibernate/search/impl and 3 other directories.
hibernate-commits at lists.jboss.org
hibernate-commits at lists.jboss.org
Wed Mar 17 12:30:50 EDT 2010
Author: epbernard
Date: 2010-03-17 12:30:48 -0400 (Wed, 17 Mar 2010)
New Revision: 19013
Added:
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/DSLTest.java
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/Month.java
Modified:
search/trunk/hibernate-search/src/main/java/org/hibernate/search/SearchFactory.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryImpl.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryContextBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermContext.java
Log:
HSEARCH-414 test on term, fuzzy and wildcard queries
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/SearchFactory.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/SearchFactory.java 2010-03-16 22:15:51 UTC (rev 19012)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/SearchFactory.java 2010-03-17 16:30:48 UTC (rev 19013)
@@ -25,6 +25,8 @@
package org.hibernate.search;
import org.apache.lucene.analysis.Analyzer;
+
+import org.hibernate.search.query.dsl.v2.QueryContextBuilder;
import org.hibernate.search.reader.ReaderProvider;
import org.hibernate.search.store.DirectoryProvider;
@@ -75,4 +77,9 @@
* class is not an indexed entity.
*/
Analyzer getAnalyzer(Class<?> clazz);
+
+ /**
+ * Return a query builder providing a fluent API to create Lucene queries
+ */
+ QueryContextBuilder buildQueryBuilder();
}
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryImpl.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryImpl.java 2010-03-16 22:15:51 UTC (rev 19012)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryImpl.java 2010-03-17 16:30:48 UTC (rev 19013)
@@ -78,6 +78,8 @@
import org.hibernate.search.filter.FilterCachingStrategy;
import org.hibernate.search.filter.MRUFilterCachingStrategy;
import org.hibernate.search.filter.ShardSensitiveOnlyFilter;
+import org.hibernate.search.query.dsl.v2.QueryContextBuilder;
+import org.hibernate.search.query.dsl.v2.impl.ConnectedQueryContextBuilder;
import org.hibernate.search.reader.ReaderProvider;
import org.hibernate.search.reader.ReaderProviderFactory;
import org.hibernate.search.store.DirectoryProvider;
@@ -476,6 +478,10 @@
return builder.getAnalyzer();
}
+ public QueryContextBuilder buildQueryBuilder() {
+ return new ConnectedQueryContextBuilder( this );
+ }
+
private void initDocumentBuilders(SearchConfiguration cfg, ReflectionManager reflectionManager) {
InitContext context = new InitContext( cfg );
Iterator<Class<?>> iter = cfg.getClassMappings();
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryBuilder.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryBuilder.java 2010-03-16 22:15:51 UTC (rev 19012)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryBuilder.java 2010-03-17 16:30:48 UTC (rev 19013)
@@ -1,7 +1,5 @@
package org.hibernate.search.query.dsl.v2;
-import org.hibernate.search.query.dsl.v2.TermContext;
-
/**
* @author Emmanuel Bernard
*/
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryContextBuilder.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryContextBuilder.java 2010-03-16 22:15:51 UTC (rev 19012)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryContextBuilder.java 2010-03-17 16:30:48 UTC (rev 19013)
@@ -1,8 +1,20 @@
package org.hibernate.search.query.dsl.v2;
-import org.apache.lucene.analysis.Analyzer;
-
/**
+ * Query builder that needs contextualization:
+ * A query builder should know which entity or analyzer it relies on.
+ *
+ * <code>
+ * QueryBuilder builder =
+ * searchFactory.buildQueryBuilder()
+ * .forEntity(Customer.class)
+ * .overridesForField("profession", "acronym-analyzer")
+ * .get();
+ * </code>
+ *
+ * overridesForField is optional (and usually not needed). This method overrides the
+ * underlying analyzer (for a given field) used to build queries.
+ *
* @author Emmanuel Bernard
*/
public interface QueryContextBuilder {
@@ -10,6 +22,10 @@
EntityContext forEntity(Class<?> entityType);
interface EntityContext {
EntityContext overridesForField(String field, String analyzerName);
+
+ /**
+ * return the query builder
+ */
QueryBuilder get();
}
}
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermContext.java 2010-03-16 22:15:51 UTC (rev 19012)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermContext.java 2010-03-17 16:30:48 UTC (rev 19013)
@@ -2,8 +2,6 @@
import org.apache.lucene.search.Query;
-import org.hibernate.search.query.dsl.v2.QueryBuilder;
-
/**
* @author Emmanuel Bernard
*/
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermContext.java 2010-03-16 22:15:51 UTC (rev 19012)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermContext.java 2010-03-17 16:30:48 UTC (rev 19013)
@@ -106,14 +106,21 @@
catch ( IOException e ) {
throw new AssertionFailure("IO exception while reading String stream??", e);
}
-
- BooleanQuery finalQuery = new BooleanQuery();
- for (String term : terms) {
- Query termQuery = createTermQuery(term);
- //termQuery.setBoost( boost );
- finalQuery.add( termQuery, BooleanClause.Occur.SHOULD );
+ if ( terms.size() == 0 ) {
+ throw new SearchException("try to search with an empty string: " + field);
}
- return finalQuery;
+ else if (terms.size() == 1 ) {
+ return createTermQuery( terms.get( 0 ) );
+ }
+ else {
+ BooleanQuery finalQuery = new BooleanQuery();
+ for (String term : terms) {
+ Query termQuery = createTermQuery(term);
+ //termQuery.setBoost( boost );
+ finalQuery.add( termQuery, BooleanClause.Occur.SHOULD );
+ }
+ return finalQuery;
+ }
}
}
Added: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/DSLTest.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/DSLTest.java (rev 0)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/DSLTest.java 2010-03-17 16:30:48 UTC (rev 19013)
@@ -0,0 +1,157 @@
+package org.hibernate.search.test.query.dsl;
+
+import java.util.List;
+
+import org.apache.lucene.search.Query;
+import org.apache.solr.analysis.LowerCaseFilterFactory;
+import org.apache.solr.analysis.NGramFilterFactory;
+import org.apache.solr.analysis.SnowballPorterFilterFactory;
+import org.apache.solr.analysis.StandardFilterFactory;
+import org.apache.solr.analysis.StandardTokenizerFactory;
+import org.apache.solr.analysis.StopFilterFactory;
+
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.search.Environment;
+import org.hibernate.search.FullTextSession;
+import org.hibernate.search.Search;
+import org.hibernate.search.annotations.Factory;
+import org.hibernate.search.cfg.SearchMapping;
+import org.hibernate.search.query.dsl.v2.QueryBuilder;
+import org.hibernate.search.test.SearchTestCase;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class DSLTest extends SearchTestCase {
+
+ public void testTermQueryOnAnalyzer() throws Exception {
+ Session session = openSession();
+ FullTextSession fts = Search.getFullTextSession( session );
+ Transaction transaction = fts.beginTransaction();
+ fts.persist( new Month("January", "Month of colder and whitening") );
+ fts.persist( new Month("February", "Month of snowboarding") );
+ transaction.commit();
+
+ fts.clear();
+
+ transaction = fts.beginTransaction();
+ final QueryBuilder monthQb = fts.getSearchFactory()
+ .buildQueryBuilder().forEntity( Month.class ).get();
+ Query
+ //regular term query
+ query = monthQb.term().on( "mythology" ).matches( "cold" ).createQuery();
+
+ assertEquals( 0, fts.createFullTextQuery( query, Month.class ).getResultSize() );
+
+ //term query based on several words
+ query = monthQb.term().on( "mythology" ).matches( "colder darker" ).createQuery();
+
+ assertEquals( 1, fts.createFullTextQuery( query, Month.class ).getResultSize() );
+
+ //term query applying the analyzer and generating one term per word
+ query = monthQb.term().on( "mythology_stem" ).matches( "snowboard" ).createQuery();
+
+ assertEquals( 1, fts.createFullTextQuery( query, Month.class ).getResultSize() );
+
+ //term query applying the analyzer and generating several terms per word
+ query = monthQb.term().on( "mythology_ngram" ).matches( "snobored" ).createQuery();
+
+ assertEquals( 1, fts.createFullTextQuery( query, Month.class ).getResultSize() );
+
+ //term query not using analyzers
+ query = monthQb.term().on( "mythology" ).matches( "Month" ).ignoreAnalyzer().createQuery();
+
+ assertEquals( 0, fts.createFullTextQuery( query, Month.class ).getResultSize() );
+
+ query = monthQb.term().on( "mythology" ).matches( "Month" ).createQuery();
+
+ final List<Month> results = fts.createFullTextQuery( query, Month.class ).list();
+ assertEquals( 2, results.size() );
+
+ for (Month entity : results) {
+ fts.delete( entity );
+ }
+ transaction.commit();
+ fts.close();
+ }
+
+ public void tesFuzzyAndWildcardQuery() throws Exception {
+ Session session = openSession();
+ FullTextSession fts = Search.getFullTextSession( session );
+ Transaction transaction = fts.beginTransaction();
+ fts.persist( new Month("January", "Month of colder and whitening") );
+ fts.persist( new Month("February", "Month of snowboarding") );
+ transaction.commit();
+
+ fts.clear();
+
+ transaction = fts.beginTransaction();
+ final QueryBuilder monthQb = fts.getSearchFactory()
+ .buildQueryBuilder().forEntity( Month.class ).get();
+ Query
+ //fuzzy search with custom threshold and prefix
+ query = monthQb
+ .term().on( "mythology" ).matches( "calder" )
+ .fuzzy()
+ .threshold( .8f )
+ .prefixLength( 1 )
+ .createQuery();
+
+ assertEquals( 1, fts.createFullTextQuery( query, Month.class ).getResultSize() );
+
+ //wildcard query
+ query = monthQb
+ .term().on( "mythology" ).matches( "mon*" )
+ .wildcard()
+ .createQuery();
+
+ assertEquals( 2, fts.createFullTextQuery( query, Month.class ).getResultSize() );
+
+ final List<Month> results = fts.createFullTextQuery( query, Month.class ).list();
+ assertEquals( 2, results.size() );
+
+ for (Month entity : results) {
+ fts.delete( entity );
+ }
+ transaction.commit();
+ fts.close();
+ }
+
+
+ @Override
+ protected Class<?>[] getMappings() {
+ return new Class<?>[] {
+ Month.class
+ };
+ }
+
+ @Override
+ protected void configure(Configuration cfg) {
+ super.configure( cfg );
+ cfg.getProperties().put( Environment.MODEL_MAPPING, MappingFactory.class.getName() );
+ }
+
+ public static class MappingFactory {
+ @Factory
+ public SearchMapping build() {
+ SearchMapping mapping = new SearchMapping();
+ mapping
+ .analyzerDef( "stemmer", StandardTokenizerFactory.class )
+ .filter( StandardFilterFactory.class )
+ .filter( LowerCaseFilterFactory.class )
+ .filter( StopFilterFactory.class )
+ .filter( SnowballPorterFilterFactory.class )
+ .param( "language", "English" )
+ .analyzerDef( "ngram", StandardTokenizerFactory.class )
+ .filter( StandardFilterFactory.class )
+ .filter( LowerCaseFilterFactory.class )
+ .filter( StopFilterFactory.class )
+ .filter( NGramFilterFactory.class )
+ .param( "minGramSize", "3" )
+ .param( "maxGramSize", "3" );
+ return mapping;
+ }
+ }
+}
Added: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/Month.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/Month.java (rev 0)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/Month.java 2010-03-17 16:30:48 UTC (rev 19013)
@@ -0,0 +1,44 @@
+package org.hibernate.search.test.query.dsl;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+import org.hibernate.search.annotations.Analyzer;
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.Fields;
+import org.hibernate.search.annotations.Indexed;
+
+/**
+ * @author Emmanuel Bernard
+ */
+ at Entity
+ at Indexed
+public class Month {
+ public Month() {}
+
+ public Month(String name, String mythology) {
+ this.name = name;
+ this.mythology = mythology;
+ }
+
+ @Id @GeneratedValue
+ public Integer getId() { return id; }
+ public void setId(Integer id) { this.id = id; }
+ private Integer id;
+
+ @Field
+ public String getName() { return name; }
+ public void setName(String name) { this.name = name; }
+ private String name;
+
+ @Fields( {
+ @Field,
+ @Field(name="mythology_stem", analyzer = @Analyzer(definition = "stemmer") ),
+ @Field(name="mythology_ngram", analyzer = @Analyzer(definition = "ngram") )
+ })
+ public String getMythology() { return mythology; }
+ public void setMythology(String mythology) { this.mythology = mythology; }
+ private String mythology;
+}
+
More information about the hibernate-commits
mailing list