[hibernate-commits] Hibernate SVN: r19672 - in search/trunk/hibernate-search/src: main/java/org/hibernate/search/query/dsl/v2 and 2 other directories.
hibernate-commits at lists.jboss.org
hibernate-commits at lists.jboss.org
Wed Jun 2 11:56:14 EDT 2010
Author: epbernard
Date: 2010-06-02 11:56:13 -0400 (Wed, 02 Jun 2010)
New Revision: 19672
Modified:
search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/DocumentBuilderIndexedEntity.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/FieldCustomization.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermMatchingContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedMultiFieldsRangeQueryBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedMultiFieldsTermQueryBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedPhraseMatchingContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedRangeMatchingContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermMatchingContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/FieldContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/Helper.java
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
Log:
HSEARCH-533 Use Hibernate Search bridge system to convert input
Pass the matching object to the field bridge.
Add posibility to ignore field bridges and pass a raw String.
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/DocumentBuilderIndexedEntity.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/DocumentBuilderIndexedEntity.java 2010-06-02 15:55:01 UTC (rev 19671)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/DocumentBuilderIndexedEntity.java 2010-06-02 15:56:13 UTC (rev 19672)
@@ -64,6 +64,7 @@
import org.hibernate.search.bridge.BridgeFactory;
import org.hibernate.search.bridge.FieldBridge;
import org.hibernate.search.bridge.LuceneOptions;
+import org.hibernate.search.bridge.StringBridge;
import org.hibernate.search.bridge.TwoWayFieldBridge;
import org.hibernate.search.bridge.TwoWayString2FieldBridgeAdaptor;
import org.hibernate.search.bridge.TwoWayStringBridge;
@@ -707,6 +708,58 @@
return -1;
}
+ public String objectToString(String fieldName, Object value) {
+ if ( fieldName == null ) {
+ throw new AssertionFailure( "Field name should not be null");
+ }
+ if ( fieldName.equals( idKeywordName ) ) {
+ return idBridge.objectToString( value );
+ }
+ else {
+ FieldBridge bridge = getBridge( metadata, fieldName );
+ if (bridge!=null) {
+ final Class<? extends FieldBridge> bridgeClass = bridge.getClass();
+ if ( TwoWayFieldBridge.class.isAssignableFrom( bridgeClass ) ) {
+ return ( (TwoWayFieldBridge) bridge ).objectToString( value );
+ }
+ else if ( StringBridge.class.isAssignableFrom( bridgeClass ) ) {
+ return ( (StringBridge) bridge ).objectToString( value );
+ }
+ throw new SearchException( "FieldBridge " + bridgeClass + "does not have a objectToString method: field "
+ + fieldName + " in " + beanClass );
+ }
+ }
+ throw new SearchException( "Unable to find field " + fieldName + " in " + beanClass );
+ }
+
+ private FieldBridge getBridge(List<String> names, List<FieldBridge> bridges, String fieldName) {
+ int index = names.indexOf( fieldName );
+ if ( index != -1 ) {
+ return bridges.get( index );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private FieldBridge getBridge(PropertiesMetadata metadata, String fieldName) {
+ //process base fields
+ FieldBridge fieldBridge = getBridge( metadata.fieldNames, metadata.fieldBridges, fieldName );
+ if ( fieldBridge != null ) return fieldBridge;
+
+ //process fields of embedded
+ final int nbrOfEmbeddedObjects = metadata.embeddedPropertiesMetadata.size();
+ for ( int index = 0; index < nbrOfEmbeddedObjects; index++ ) {
+ fieldBridge = getBridge( metadata.embeddedPropertiesMetadata.get( index ), fieldName );
+ if ( fieldBridge != null ) return fieldBridge;
+ }
+
+ //process class bridges
+ fieldBridge = getBridge( metadata.classNames, metadata.classBridges, fieldName );
+ if ( fieldBridge != null ) return fieldBridge;
+ return null;
+ }
+
/**
* Checks whether all involved bridges are two way string bridges. If so we can optimize document retrieval
* by using <code>FieldSelector</code>. See HSEARCH-213.
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/FieldCustomization.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/FieldCustomization.java 2010-06-02 15:55:01 UTC (rev 19671)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/FieldCustomization.java 2010-06-02 15:56:13 UTC (rev 19672)
@@ -20,4 +20,10 @@
* (It is usually a good idea to apply the analyzer)
*/
T ignoreAnalyzer();
+
+ /**
+ * Do not try and find the field bridge nor apply the object / string conversion
+ * matching objects should be of type String in this case.
+ */
+ T ignoreFieldBridge();
}
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermMatchingContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermMatchingContext.java 2010-06-02 15:55:01 UTC (rev 19671)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermMatchingContext.java 2010-06-02 15:56:13 UTC (rev 19672)
@@ -5,9 +5,12 @@
*/
public interface TermMatchingContext extends FieldCustomization<TermMatchingContext> {
/**
- * text searched in the term query (the term is pre-analyzer unless ignoreAnalyzer is called)
+ * Value searched in the field or fields.
+ * The value is passed to the field's:
+ * - field bridge
+ * - analyzer (unless ignoreAnalyzer is called).
*/
- TermTermination matching(String text);
+ TermTermination matching(Object value);
/**
* field / property the term query is executed on
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedMultiFieldsRangeQueryBuilder.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedMultiFieldsRangeQueryBuilder.java 2010-06-02 15:55:01 UTC (rev 19671)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedMultiFieldsRangeQueryBuilder.java 2010-06-02 15:56:13 UTC (rev 19672)
@@ -9,6 +9,7 @@
import org.apache.lucene.search.TermRangeQuery;
import org.hibernate.annotations.common.AssertionFailure;
+import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
import org.hibernate.search.query.dsl.v2.RangeTerminationExcludable;
/**
@@ -63,10 +64,25 @@
final Query perFieldQuery;
final String fieldName = fieldContext.getField();
final Analyzer queryAnalyzer = queryContext.getQueryAnalyzer();
- final Object from = rangeContext.getFrom();
- final String lowerTerm = from == null ? null : Helper.getAnalyzedTerm( fieldName, from, "from", queryAnalyzer );
- final Object to = rangeContext.getTo();
- final String upperTerm = to == null ? null : Helper.getAnalyzedTerm( fieldName, to, "to", queryAnalyzer );
+
+ final DocumentBuilderIndexedEntity<?> documentBuilder = Helper.getDocumentBuilder( queryContext );
+
+ final Object fromObject = rangeContext.getFrom();
+ final String fromString = fieldContext.isIgnoreFieldBridge() ?
+ fromObject == null ? null : fromObject.toString() :
+ documentBuilder.objectToString( fieldName, fromObject );
+ final String lowerTerm = fromString == null ?
+ null :
+ Helper.getAnalyzedTerm( fieldName, fromString, "from", queryAnalyzer, fieldContext );
+
+ final Object toObject = rangeContext.getTo();
+ final String toString = fieldContext.isIgnoreFieldBridge() ?
+ toObject == null ? null : toObject.toString() :
+ documentBuilder.objectToString( fieldName, toObject );
+ final String upperTerm = toString == null ?
+ null :
+ Helper.getAnalyzedTerm( fieldName, toString, "to", queryAnalyzer, fieldContext );
+
perFieldQuery = new TermRangeQuery(
fieldName,
lowerTerm,
@@ -76,4 +92,6 @@
);
return fieldContext.getFieldCustomizer().setWrappedQuery( perFieldQuery ).createQuery();
}
+
+
}
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedMultiFieldsTermQueryBuilder.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedMultiFieldsTermQueryBuilder.java 2010-06-02 15:55:01 UTC (rev 19671)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedMultiFieldsTermQueryBuilder.java 2010-06-02 15:56:13 UTC (rev 19672)
@@ -15,25 +15,26 @@
import org.hibernate.annotations.common.AssertionFailure;
import org.hibernate.search.SearchException;
+import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
import org.hibernate.search.query.dsl.v2.TermTermination;
/**
* @author Emmanuel Bernard
*/
public class ConnectedMultiFieldsTermQueryBuilder implements TermTermination {
- private final String text;
+ private final Object value;
private final QueryCustomizer queryCustomizer;
private final TermQueryContext termContext;
private final List<FieldContext> fieldContexts;
private final QueryBuildingContext queryContext;
public ConnectedMultiFieldsTermQueryBuilder(TermQueryContext termContext,
- String text,
+ Object value,
List<FieldContext> fieldContexts,
QueryCustomizer queryCustomizer,
QueryBuildingContext queryContext) {
this.termContext = termContext;
- this.text = text;
+ this.value = value;
this.queryContext = queryContext;
this.queryCustomizer = queryCustomizer;
this.fieldContexts = fieldContexts;
@@ -55,6 +56,10 @@
public Query createQuery(FieldContext fieldContext) {
final Query perFieldQuery;
+ final DocumentBuilderIndexedEntity<?> documentBuilder = Helper.getDocumentBuilder( queryContext );
+ String text = fieldContext.isIgnoreFieldBridge() ?
+ value.toString() :
+ documentBuilder.objectToString( fieldContext.getField(), value );
if ( fieldContext.isIgnoreAnalyzer() ) {
perFieldQuery = createTermQuery( fieldContext, text );
}
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedPhraseMatchingContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedPhraseMatchingContext.java 2010-06-02 15:55:01 UTC (rev 19671)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedPhraseMatchingContext.java 2010-06-02 15:56:13 UTC (rev 19672)
@@ -57,4 +57,9 @@
}
return this;
}
+
+ public PhraseMatchingContext ignoreFieldBridge() {
+ //this is a no-op
+ return this;
+ }
}
\ No newline at end of file
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedRangeMatchingContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedRangeMatchingContext.java 2010-06-02 15:55:01 UTC (rev 19671)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedRangeMatchingContext.java 2010-06-02 15:56:13 UTC (rev 19672)
@@ -88,4 +88,11 @@
}
return this;
}
+
+ public RangeMatchingContext ignoreFieldBridge() {
+ for ( FieldContext fieldContext : getCurrentFieldContexts() ) {
+ fieldContext.setIgnoreFieldBridge( true );
+ }
+ return this;
+ }
}
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermMatchingContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermMatchingContext.java 2010-06-02 15:55:01 UTC (rev 19671)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermMatchingContext.java 2010-06-02 15:56:13 UTC (rev 19672)
@@ -38,8 +38,8 @@
}
}
- public TermTermination matching(String text) {
- return new ConnectedMultiFieldsTermQueryBuilder( termContext, text, fieldContexts, queryCustomizer, queryContext);
+ public TermTermination matching(Object value) {
+ return new ConnectedMultiFieldsTermQueryBuilder( termContext, value, fieldContexts, queryCustomizer, queryContext);
}
public TermMatchingContext andField(String field) {
@@ -65,4 +65,11 @@
}
return this;
}
+
+ public TermMatchingContext ignoreFieldBridge() {
+ for ( FieldContext fieldContext : getCurrentFieldContexts() ) {
+ fieldContext.setIgnoreFieldBridge( true );
+ }
+ return this;
+ }
}
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/FieldContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/FieldContext.java 2010-06-02 15:55:01 UTC (rev 19671)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/FieldContext.java 2010-06-02 15:56:13 UTC (rev 19672)
@@ -9,6 +9,7 @@
private final String field;
private boolean ignoreAnalyzer;
private final QueryCustomizer fieldCustomizer;
+ private boolean ignoreFieldBridge;
public FieldContext(String field) {
this.field = field;
@@ -30,4 +31,12 @@
public QueryCustomizer getFieldCustomizer() {
return fieldCustomizer;
}
+
+ public boolean isIgnoreFieldBridge() {
+ return ignoreFieldBridge;
+ }
+
+ public void setIgnoreFieldBridge(boolean ignoreFieldBridge) {
+ this.ignoreFieldBridge = ignoreFieldBridge;
+ }
}
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/Helper.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/Helper.java 2010-06-02 15:55:01 UTC (rev 19671)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/Helper.java 2010-06-02 15:56:13 UTC (rev 19672)
@@ -12,6 +12,8 @@
import org.hibernate.annotations.common.AssertionFailure;
import org.hibernate.search.SearchException;
+import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
+import org.hibernate.search.engine.SearchFactoryImplementor;
/**
* @author Emmanuel Bernard
@@ -20,13 +22,22 @@
/**
* return the analyzed value for a given field. If several terms are created, an exception is raised.
*/
- static String getAnalyzedTerm(String fieldName, Object value, String name, Analyzer queryAnalyzer) {
+ static String getAnalyzedTerm(String fieldName, String value, String name, Analyzer queryAnalyzer, FieldContext fieldContext) {
+ if ( fieldContext.isIgnoreAnalyzer() ) return value;
+
try {
final List<String> termsFromText = getAllTermsFromText(
fieldName, value.toString(), queryAnalyzer
);
if (termsFromText.size() > 1) {
- throw new SearchException( "The " + name + " parameter leads to several terms when analyzed");
+ StringBuilder error = new StringBuilder( "The ")
+ .append( name )
+ .append( " parameter leads to several terms when analyzed: " );
+ for ( String term : termsFromText ) {
+ error.append( term ).append( ", " );
+ }
+ final int length = error.length();
+ throw new SearchException( error.delete( length - 1, length ).toString() );
}
return termsFromText.size() == 0 ? null : termsFromText.get( 0 );
}
@@ -53,4 +64,14 @@
stream.close();
return terms;
}
+
+ static DocumentBuilderIndexedEntity<?> getDocumentBuilder(QueryBuildingContext queryContext) {
+ final SearchFactoryImplementor factory = queryContext.getFactory();
+ final Class<?> type = queryContext.getEntityType();
+ DocumentBuilderIndexedEntity<?> builder = factory.getDocumentBuilderIndexedEntity( type );
+ if ( builder == null ) {
+ throw new AssertionFailure( "Class in not indexed: " + type );
+ }
+ return builder;
+ }
}
Modified: 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 2010-06-02 15:55:01 UTC (rev 19671)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/DSLTest.java 2010-06-02 15:56:13 UTC (rev 19672)
@@ -33,6 +33,29 @@
*/
public class DSLTest extends SearchTestCase {
+ public void testUseOfFieldBridge() throws Exception {
+ FullTextSession fts = initData();
+
+ Transaction transaction = fts.beginTransaction();
+ final QueryBuilder monthQb = fts.getSearchFactory()
+ .buildQueryBuilder().forEntity( Month.class ).get();
+ Query
+
+ query = monthQb.keyword().onField( "monthValue" ).matching( 2 ).createQuery();
+ assertEquals( 1, fts.createFullTextQuery( query, Month.class ).getResultSize() );
+
+ query = monthQb.keyword()
+ .onField( "monthValue" )
+ .ignoreFieldBridge()
+ .matching( "2" )
+ .createQuery();
+ assertEquals( 1, fts.createFullTextQuery( query, Month.class ).getResultSize() );
+
+ transaction.commit();
+
+ cleanData( fts );
+ }
+
public void testTermQueryOnAnalyzer() throws Exception {
FullTextSession fts = initData();
@@ -264,6 +287,19 @@
range()
.onField( "estimatedCreation" )
.andField( "justfortest" )
+ .ignoreFieldBridge().ignoreAnalyzer()
+ .from( from )
+ .to( to ).exclude()
+ .createQuery();
+
+ assertEquals( 1, fts.createFullTextQuery( query, Month.class ).getResultSize() );
+
+ query = monthQb.
+ range()
+ .onField( "estimatedCreation" )
+ .ignoreFieldBridge()
+ .andField( "justfortest" )
+ .ignoreFieldBridge().ignoreAnalyzer()
.from( DateTools.dateToString( from, DateTools.Resolution.MINUTE ) )
.to( DateTools.dateToString( to, DateTools.Resolution.MINUTE ) ).exclude()
.createQuery();
@@ -273,7 +309,8 @@
range()
.onField( "estimatedCreation" )
.andField( "justfortest" )
- .below( DateTools.dateToString( to, DateTools.Resolution.MINUTE ) )
+ .ignoreFieldBridge().ignoreAnalyzer()
+ .below( to )
.createQuery();
FullTextQuery hibQuery = fts.createFullTextQuery( query, Month.class );
@@ -283,7 +320,33 @@
query = monthQb.
range()
.onField( "estimatedCreation" )
+ .ignoreFieldBridge()
.andField( "justfortest" )
+ .ignoreFieldBridge().ignoreAnalyzer()
+ .below( DateTools.dateToString( to, DateTools.Resolution.MINUTE ) )
+ .createQuery();
+
+ hibQuery = fts.createFullTextQuery( query, Month.class );
+ assertEquals( 1, hibQuery.getResultSize() );
+ assertEquals( "January", ( (Month) hibQuery.list().get( 0 ) ).getName() );
+
+ query = monthQb.
+ range()
+ .onField( "estimatedCreation" )
+ .andField( "justfortest" )
+ .ignoreFieldBridge().ignoreAnalyzer()
+ .above( to )
+ .createQuery();
+ hibQuery = fts.createFullTextQuery( query, Month.class );
+ assertEquals( 1, hibQuery.getResultSize() );
+ assertEquals( "February", ( (Month) hibQuery.list().get( 0 ) ).getName() );
+
+ query = monthQb.
+ range()
+ .onField( "estimatedCreation" )
+ .ignoreFieldBridge()
+ .andField( "justfortest" )
+ .ignoreFieldBridge().ignoreAnalyzer()
.above( DateTools.dateToString( to, DateTools.Resolution.MINUTE ) )
.createQuery();
hibQuery = fts.createFullTextQuery( query, Month.class );
@@ -484,12 +547,14 @@
calendar.set(0 + 1900, 2, 12, 0, 0, 0);
fts.persist( new Month(
"January",
+ 1,
"Month of colder and whitening",
"Historically colder than any other month in the northern hemisphere",
calendar.getTime() ) );
calendar.set(100 + 1900, 2, 12, 0, 0, 0);
fts.persist( new Month(
"February",
+ 2,
"Month of snowboarding",
"Historically, the month where we make babies while watching the whitening landscape",
calendar.getTime() ) );
Modified: 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 2010-06-02 15:55:01 UTC (rev 19671)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/Month.java 2010-06-02 15:56:13 UTC (rev 19672)
@@ -19,13 +19,15 @@
@Entity
@Indexed
public class Month {
+
public Month() {}
- public Month(String name, String mythology, String history, Date estimatedCreation) {
+ public Month(String name, int monthValue, String mythology, String history, Date estimatedCreation) {
this.name = name;
this.mythology = mythology;
this.history = history;
this.estimatedCreation = estimatedCreation;
+ this.monthValue = monthValue;
}
@Id @GeneratedValue
@@ -33,6 +35,11 @@
public void setId(Integer id) { this.id = id; }
private Integer id;
+ @Field(index = Index.NO_NORMS)
+ public int getMonthValue() { return monthValue; }
+ public void setMonthValue(int monthValue) { this.monthValue = monthValue; }
+ private int monthValue;
+
@Field
public String getName() { return name; }
public void setName(String name) { this.name = name; }
More information about the hibernate-commits
mailing list