[hibernate-commits] Hibernate SVN: r15389 - in search/trunk: src/java/org/hibernate/search/annotations and 3 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Fri Oct 24 13:42:28 EDT 2008


Author: epbernard
Date: 2008-10-24 13:42:28 -0400 (Fri, 24 Oct 2008)
New Revision: 15389

Added:
   search/trunk/src/test/org/hibernate/search/test/query/boost/
   search/trunk/src/test/org/hibernate/search/test/query/boost/BoostedDescriptionLibrary.java
   search/trunk/src/test/org/hibernate/search/test/query/boost/BoostedFieldDescriptionLibrary.java
   search/trunk/src/test/org/hibernate/search/test/query/boost/BoostedGetDescriptionLibrary.java
   search/trunk/src/test/org/hibernate/search/test/query/boost/FieldBoostTest.java
   search/trunk/src/test/org/hibernate/search/test/query/boost/Library.java
Modified:
   search/trunk/doc/reference/en/modules/mapping.xml
   search/trunk/src/java/org/hibernate/search/annotations/Field.java
   search/trunk/src/java/org/hibernate/search/engine/DocumentBuilder.java
Log:
HSEARCH-170 @Boost is now supposed on @Field in a cummulative way

Modified: search/trunk/doc/reference/en/modules/mapping.xml
===================================================================
--- search/trunk/doc/reference/en/modules/mapping.xml	2008-10-24 15:48:35 UTC (rev 15388)
+++ search/trunk/doc/reference/en/modules/mapping.xml	2008-10-24 17:42:28 UTC (rev 15389)
@@ -492,13 +492,13 @@
       <title>Boost factor</title>
 
       <para>Lucene has the notion of <emphasis>boost factor</emphasis>. It's a
-      way to give more weigth to a field or to an indexed element over an
-      other during the indexation process. You can use
-      <literal>@Boost</literal> at the field or the class level.</para>
+      way to give more weigth to a field or to an indexed element over others
+      during the indexation process. You can use <literal>@Boost</literal> at
+      the @Field, method or class level.</para>
 
       <programlisting>@Entity
 @Indexed(index="indexes/essays")
-<emphasis role="bold">@Boost(2)</emphasis>
+<emphasis role="bold">@Boost(1.7f)</emphasis>
 public class Essay {
     ...
 
@@ -506,21 +506,34 @@
     @DocumentId
     public Long getId() { return id; }
 
-    @Field(name="Abstract", index=Index.TOKENIZED, store=Store.YES)
-    <emphasis role="bold">@Boost(2.5f)</emphasis>
+    @Field(name="Abstract", index=Index.TOKENIZED, store=Store.YES, boost=<emphasis
+          role="bold">@Boost(2f)</emphasis>)
+    <emphasis role="bold">@Boost(1.5f)</emphasis>
     public String getSummary() { return summary; }
 
     @Lob
-    @Field(index=Index.TOKENIZED)
+    @Field(index=Index.TOKENIZED, boost=<emphasis role="bold">@Boost(1.2f)</emphasis>)
     public String getText() { return text; }
+
+    @Field
+    public String getISBN() { return isbn; }
+
 }        </programlisting>
 
       <para>In our example, Essay's probability to reach the top of the search
-      list will be multiplied by 2 and the summary field will be 2.5 more
-      important than the test field. Note that this explaination is actually
-      wrong, but it is simple and close enought to the reality. Please check
-      the Lucene documentation or the excellent <citetitle>Lucene In Action
-      </citetitle> from Otis Gospodnetic and Erik Hatcher.</para>
+      list will be multiplied by 1.7. The <methodname>summary</methodname>
+      field will be 2.5 (2 * 1.5) more important than the
+      <methodname>isbn</methodname> field. The <methodname>text</methodname>
+      field will be 1.2 times more important than the
+      <methodname>isbn</methodname> field. Note that this explanation in
+      strictest terms is actually wrong, but it is simple and close enough to
+      reality for all practical purposes. Please check the Lucene
+      documentation or the excellent <citetitle>Lucene In Action </citetitle>
+      from Otis Gospodnetic and Erik Hatcher.</para>
+
+      <para><methodname>@Field.boost</methodname>,
+      <classname>@Boost</classname> on a property and
+      <classname>@Boost</classname> on a class are all cumulative.</para>
     </section>
 
     <section id="analyzer">
@@ -1206,4 +1219,4 @@
 			</programlisting>
     </section>
   </section>
-</chapter>
+</chapter>
\ No newline at end of file

Modified: search/trunk/src/java/org/hibernate/search/annotations/Field.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/annotations/Field.java	2008-10-24 15:48:35 UTC (rev 15388)
+++ search/trunk/src/java/org/hibernate/search/annotations/Field.java	2008-10-24 17:42:28 UTC (rev 15389)
@@ -49,9 +49,14 @@
 	 */
 	Analyzer analyzer() default @Analyzer;
 
+
 	/**
 	 * Field bridge used. Default is autowired.
 	 */
+	Boost boost() default @Boost( value = 1.0F );
+
+	/**
+	 * Field bridge used. Default is autowired.
+	 */
 	FieldBridge bridge() default @FieldBridge;
-
 }

Modified: search/trunk/src/java/org/hibernate/search/engine/DocumentBuilder.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/engine/DocumentBuilder.java	2008-10-24 15:48:35 UTC (rev 15388)
+++ search/trunk/src/java/org/hibernate/search/engine/DocumentBuilder.java	2008-10-24 17:42:28 UTC (rev 15389)
@@ -80,7 +80,7 @@
 	public static final String CLASS_FIELDNAME = "_hibernate_class";
 	private TwoWayFieldBridge idBridge;
 	private Set<Class<?>> mappedSubclasses = new HashSet<Class<?>>();
-	private ReflectionManager reflectionManager;
+	private ReflectionManager reflectionManager; //available only during initializationa nd post-initialization
 	private int level = 0;
 	private int maxLevel = Integer.MAX_VALUE;
 	private final ScopedAnalyzer analyzer = new ScopedAnalyzer();
@@ -105,7 +105,7 @@
 		this.beanClass = clazz;
 		this.directoryProviders = directoryProviders;
 		this.shardingStrategy = shardingStrategy;
-		//FIXME get rid of it when boost is stored?
+		//set to null after post-initialization
 		this.reflectionManager = reflectionManager;
 		this.similarity = context.getDefaultSimilarity();
 
@@ -126,7 +126,7 @@
 			ProvidedId provided = findProvidedId( clazz, reflectionManager );
 			if ( provided == null ) throw new SearchException( "No document id in: " + clazz.getName() );
 
-			idBridge = BridgeFactory.extractTwoWayType(provided.bridge());
+			idBridge = BridgeFactory.extractTwoWayType( provided.bridge() );
 			idKeywordName = provided.name();
 		}
 		//if composite id, use of (a, b) in ((1,2)TwoWayString2FieldBridgeAdaptor, (3,4)) fails on most database
@@ -143,12 +143,12 @@
 		this.directoryProviders = null;
 		this.shardingStrategy = null;
 
-		//FIXME get rid of it when boost is stored?
+
 		this.reflectionManager = reflectionManager;
 		this.similarity = context.getDefaultSimilarity();
 
 		init( clazz, context, reflectionManager );
-		if (rootPropertiesMetadata.containedInGetters.size() == 0) {
+		if ( rootPropertiesMetadata.containedInGetters.size() == 0 ) {
 			this.entityState = EntityState.NON_INDEXABLE;
 		}
 	}
@@ -156,7 +156,7 @@
 	private ProvidedId findProvidedId(XClass clazz, ReflectionManager reflectionManager) {
 		ProvidedId id = null;
 		XClass currentClass = clazz;
-		while ( id == null && ( ! reflectionManager.equals( currentClass, Object.class ) ) ) {
+		while ( id == null && ( !reflectionManager.equals( currentClass, Object.class ) ) ) {
 			id = currentClass.getAnnotation( ProvidedId.class );
 			currentClass = clazz.getSuperclass();
 		}
@@ -303,7 +303,7 @@
 					throw new SearchException(
 							"Bridge for document id does not implement TwoWayFieldBridge: " + member.getName() );
 				}
-				idBoost = getBoost( member );
+				idBoost = getBoost( member, null );
 				setAccessible( member );
 				idGetter = member;
 			}
@@ -317,6 +317,7 @@
 				propertiesMetadata.fieldIndex.add( getIndex( Index.UN_TOKENIZED ) );
 				propertiesMetadata.fieldTermVectors.add( getTermVector( TermVector.NO ) );
 				propertiesMetadata.fieldBridges.add( BridgeFactory.guessType( null, member, reflectionManager ) );
+				propertiesMetadata.fieldBoosts.add( getBoost( member, null ) );
 				// property > entity analyzer (no field analyzer)
 				Analyzer analyzer = getAnalyzer( member, context );
 				if ( analyzer == null ) analyzer = propertiesMetadata.analyzer;
@@ -351,7 +352,7 @@
 			}
 			maxLevel = potentialLevel > maxLevel ? maxLevel : potentialLevel;
 			level++;
-			                                                             
+
 			XClass elementClass;
 			if ( void.class == embeddedAnn.targetElement() ) {
 				elementClass = member.getElementClass();
@@ -375,7 +376,7 @@
 				propertiesMetadata.embeddedGetters.add( member );
 				PropertiesMetadata metadata = new PropertiesMetadata();
 				propertiesMetadata.embeddedPropertiesMetadata.add( metadata );
-				metadata.boost = getBoost( member );
+				metadata.boost = getBoost( member, null );
 				//property > entity analyzer
 				Analyzer analyzer = getAnalyzer( member, context );
 				metadata.analyzer = analyzer != null ? analyzer : propertiesMetadata.analyzer;
@@ -441,6 +442,7 @@
 		propertiesMetadata.fieldNames.add( fieldName );
 		propertiesMetadata.fieldStore.add( getStore( fieldAnn.store() ) );
 		propertiesMetadata.fieldIndex.add( getIndex( fieldAnn.index() ) );
+		propertiesMetadata.fieldBoosts.add( getBoost(member, fieldAnn) );
 		propertiesMetadata.fieldTermVectors.add( getTermVector( fieldAnn.termVector() ) );
 		propertiesMetadata.fieldBridges.add( BridgeFactory.guessType( fieldAnn, member, reflectionManager ) );
 
@@ -452,6 +454,14 @@
 		}
 	}
 
+	private Float getBoost(XProperty member, org.hibernate.search.annotations.Field fieldAnn) {
+		float computedBoost = 1.0f;
+		Boost boostAnn = member.getAnnotation( Boost.class );
+		if (boostAnn != null) computedBoost = boostAnn.value();
+		if (fieldAnn != null) computedBoost *= fieldAnn.boost().value();
+		return computedBoost;
+	}
+
 	private String buildEmbeddedPrefix(String prefix, IndexedEmbedded embeddedAnn, XProperty member) {
 		String localPrefix = prefix;
 		if ( ".".equals( embeddedAnn.prefix() ) ) {
@@ -509,7 +519,7 @@
 		}
 	}
 
-	private Float getBoost(XAnnotatedElement element) {
+	private Float getBoost(XClass element) {
 		if ( element == null ) return null;
 		Boost boost = element.getAnnotation( Boost.class );
 		return boost != null ?
@@ -541,14 +551,14 @@
 					Serializable currentId = luceneWork.getId();
 					//currentId != null => either ADD or Delete work
 					if ( currentId != null && currentId.equals( id ) ) { //find a way to use Type.equals(x,y)
-						if (workType == WorkType.DELETE) { //TODO add PURGE?
+						if ( workType == WorkType.DELETE ) { //TODO add PURGE?
 							//DELETE should have precedence over any update before (HSEARCH-257)
 							//if an Add work is here, remove it
 							//if an other delete is here remember but still search for Add
-							if (luceneWork instanceof AddLuceneWork) {
+							if ( luceneWork instanceof AddLuceneWork ) {
 								toDelete.add( luceneWork );
 							}
-							else if (luceneWork instanceof DeleteLuceneWork) {
+							else if ( luceneWork instanceof DeleteLuceneWork ) {
 								duplicateDelete = true;
 							}
 						}
@@ -560,10 +570,10 @@
 					//TODO do something to avoid multiple PURGE ALL and OPTIMIZE
 				}
 			}
-			for ( LuceneWork luceneWork : toDelete ) {
+			for (LuceneWork luceneWork : toDelete) {
 				toDelete.remove( luceneWork );
 			}
-			if (duplicateDelete) return;
+			if ( duplicateDelete ) return;
 
 			String idInString = idBridge.objectToString( id );
 			if ( workType == WorkType.ADD ) {
@@ -660,13 +670,13 @@
 	public Document getDocument(T instance, Serializable id) {
 		Document doc = new Document();
 		final Class<?> entityType = Hibernate.getClass( instance );
-		XClass instanceClass = reflectionManager.toXClass( entityType );
+		//XClass instanceClass = reflectionManager.toXClass( entityType );
 		if ( rootPropertiesMetadata.boost != null ) {
 			doc.setBoost( rootPropertiesMetadata.boost );
 		}
 		{
 			Field classField =
-					new Field( CLASS_FIELDNAME, instanceClass.getName(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO );
+					new Field( CLASS_FIELDNAME, entityType.getName(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO );
 			doc.add( classField );
 			LuceneOptions luceneOptions = new LuceneOptionsImpl( Field.Store.YES,
 					Field.Index.UN_TOKENIZED, Field.TermVector.NO, idBoost );
@@ -690,7 +700,7 @@
 			Object value = getMemberValue( unproxiedInstance, member );
 			propertiesMetadata.fieldBridges.get( i ).set(
 					propertiesMetadata.fieldNames.get( i ), value, doc,
-					propertiesMetadata.getFieldLuceneOptions( i, getBoost( member ) ) );
+					propertiesMetadata.getFieldLuceneOptions( i ) );
 		}
 		for (int i = 0; i < propertiesMetadata.embeddedGetters.size(); i++) {
 			XMember member = propertiesMetadata.embeddedGetters.get( i );
@@ -744,15 +754,15 @@
 	}
 
 	public DirectoryProvider[] getDirectoryProviders() {
-		if( entityState != EntityState.INDEXED ) {
-			throw new AssertionFailure("Contained in only entity: getDirectoryProvider should not have been called.");
+		if ( entityState != EntityState.INDEXED ) {
+			throw new AssertionFailure( "Contained in only entity: getDirectoryProvider should not have been called." );
 		}
 		return directoryProviders;
 	}
 
 	public IndexShardingStrategy getDirectoryProviderSelectionStrategy() {
-		if( entityState != EntityState.INDEXED ) {
-			throw new AssertionFailure("Contained in only entity: getDirectoryProviderSelectionStrategy should not have been called.");
+		if ( entityState != EntityState.INDEXED ) {
+			throw new AssertionFailure( "Contained in only entity: getDirectoryProviderSelectionStrategy should not have been called." );
 		}
 		return shardingStrategy;
 	}
@@ -857,7 +867,8 @@
 	}
 
 	public void postInitialize(Set<Class<?>> indexedClasses) {
-		if (entityState == EntityState.NON_INDEXABLE) throw new AssertionFailure("A non indexed entity is post processed");
+		if ( entityState == EntityState.NON_INDEXABLE )
+			throw new AssertionFailure( "A non indexed entity is post processed" );
 		//this method does not requires synchronization
 		Class plainClass = reflectionManager.toClass( beanClass );
 		Set<Class<?>> tempMappedSubclasses = new HashSet<Class<?>>();
@@ -875,6 +886,7 @@
 			}
 			superClass = superClass.getSuperclass();
 		}
+		this.reflectionManager = null;
 	}
 
 	public EntityState getEntityState() {
@@ -904,6 +916,7 @@
 		public final List<FieldBridge> fieldBridges = new ArrayList<FieldBridge>();
 		public final List<Field.Store> fieldStore = new ArrayList<Field.Store>();
 		public final List<Field.Index> fieldIndex = new ArrayList<Field.Index>();
+		public final List<Float> fieldBoosts = new ArrayList<Float>();
 		public final List<Field.TermVector> fieldTermVectors = new ArrayList<Field.TermVector>();
 		public final List<XMember> embeddedGetters = new ArrayList<XMember>();
 		public final List<PropertiesMetadata> embeddedPropertiesMetadata = new ArrayList<PropertiesMetadata>();
@@ -929,9 +942,10 @@
 			return options;
 		}
 
-		private LuceneOptions getFieldLuceneOptions(int i, Float boost) {
-			LuceneOptions options = new LuceneOptionsImpl( fieldStore.get( i ),
-					fieldIndex.get( i ), fieldTermVectors.get( i ), boost );
+		private LuceneOptions getFieldLuceneOptions(int i) {
+			LuceneOptions options;
+			options = new LuceneOptionsImpl( fieldStore.get( i ),
+					fieldIndex.get( i ), fieldTermVectors.get( i ), fieldBoosts.get( i ) );
 			return options;
 		}
 	}

Added: search/trunk/src/test/org/hibernate/search/test/query/boost/BoostedDescriptionLibrary.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/query/boost/BoostedDescriptionLibrary.java	                        (rev 0)
+++ search/trunk/src/test/org/hibernate/search/test/query/boost/BoostedDescriptionLibrary.java	2008-10-24 17:42:28 UTC (rev 15389)
@@ -0,0 +1,67 @@
+package org.hibernate.search.test.query.boost;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+import org.apache.lucene.analysis.standard.StandardAnalyzer;
+
+import org.hibernate.search.annotations.Analyzer;
+import org.hibernate.search.annotations.Boost;
+import org.hibernate.search.annotations.DocumentId;
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.Index;
+import org.hibernate.search.annotations.Indexed;
+import org.hibernate.search.annotations.Store;
+
+/**
+ * @author John Griffin
+ */
+ at Entity
+ at Indexed
+ at Analyzer(impl = StandardAnalyzer.class)
+public class BoostedDescriptionLibrary {
+	private int id;
+	private String title;
+	private String author;
+	private String description;
+
+	@Id
+	@GeneratedValue
+	@DocumentId
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	@Field(store = Store.YES, index = Index.TOKENIZED)
+	public String getTitle() {
+		return title;
+	}
+
+	public void setTitle(String title) {
+		this.title = title;
+	}
+
+	@Field(store = Store.YES, index = Index.TOKENIZED)
+	public String getAuthor() {
+		return author;
+	}
+
+	public void setAuthor(String author) {
+		this.author = author;
+	}
+
+	@Boost(2.0F)
+	@Field(store = Store.YES, index = Index.TOKENIZED, boost = @Boost(2.0F))
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+}
\ No newline at end of file

Added: search/trunk/src/test/org/hibernate/search/test/query/boost/BoostedFieldDescriptionLibrary.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/query/boost/BoostedFieldDescriptionLibrary.java	                        (rev 0)
+++ search/trunk/src/test/org/hibernate/search/test/query/boost/BoostedFieldDescriptionLibrary.java	2008-10-24 17:42:28 UTC (rev 15389)
@@ -0,0 +1,66 @@
+package org.hibernate.search.test.query.boost;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+import org.apache.lucene.analysis.standard.StandardAnalyzer;
+
+import org.hibernate.search.annotations.Analyzer;
+import org.hibernate.search.annotations.Boost;
+import org.hibernate.search.annotations.DocumentId;
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.Index;
+import org.hibernate.search.annotations.Indexed;
+import org.hibernate.search.annotations.Store;
+
+/**
+ * @author John Griffin
+ */
+ at Entity
+ at Indexed
+ at Analyzer(impl = StandardAnalyzer.class)
+public class BoostedFieldDescriptionLibrary {
+	private int id;
+	private String title;
+	private String author;
+	private String description;
+
+	@Id
+	@GeneratedValue
+	@DocumentId
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	@Field(store = Store.YES, index = Index.TOKENIZED)
+	public String getTitle() {
+		return title;
+	}
+
+	public void setTitle(String title) {
+		this.title = title;
+	}
+
+	@Field(store = Store.YES, index = Index.TOKENIZED)
+	public String getAuthor() {
+		return author;
+	}
+
+	public void setAuthor(String author) {
+		this.author = author;
+	}
+
+	@Field(store = Store.YES, index = Index.TOKENIZED, boost = @Boost(2.0F))
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+}
\ No newline at end of file

Added: search/trunk/src/test/org/hibernate/search/test/query/boost/BoostedGetDescriptionLibrary.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/query/boost/BoostedGetDescriptionLibrary.java	                        (rev 0)
+++ search/trunk/src/test/org/hibernate/search/test/query/boost/BoostedGetDescriptionLibrary.java	2008-10-24 17:42:28 UTC (rev 15389)
@@ -0,0 +1,67 @@
+package org.hibernate.search.test.query.boost;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+import org.apache.lucene.analysis.standard.StandardAnalyzer;
+
+import org.hibernate.search.annotations.Analyzer;
+import org.hibernate.search.annotations.Boost;
+import org.hibernate.search.annotations.DocumentId;
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.Index;
+import org.hibernate.search.annotations.Indexed;
+import org.hibernate.search.annotations.Store;
+
+/**
+ * @author John Griffin
+ */
+ at Entity
+ at Indexed
+ at Analyzer(impl = StandardAnalyzer.class)
+public class BoostedGetDescriptionLibrary {
+	private int id;
+	private String title;
+	private String author;
+	private String description;
+
+	@Id
+	@GeneratedValue
+	@DocumentId
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	@Field(store = Store.YES, index = Index.TOKENIZED)
+	public String getTitle() {
+		return title;
+	}
+
+	public void setTitle(String title) {
+		this.title = title;
+	}
+
+	@Field(store = Store.YES, index = Index.TOKENIZED)
+	public String getAuthor() {
+		return author;
+	}
+
+	public void setAuthor(String author) {
+		this.author = author;
+	}
+
+	@Boost(2.0F)
+	@Field(store = Store.YES, index = Index.TOKENIZED)
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+}
\ No newline at end of file

Added: search/trunk/src/test/org/hibernate/search/test/query/boost/FieldBoostTest.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/query/boost/FieldBoostTest.java	                        (rev 0)
+++ search/trunk/src/test/org/hibernate/search/test/query/boost/FieldBoostTest.java	2008-10-24 17:42:28 UTC (rev 15389)
@@ -0,0 +1,196 @@
+package org.hibernate.search.test.query.boost;
+
+import java.util.List;
+
+import org.apache.lucene.analysis.standard.StandardAnalyzer;
+import org.apache.lucene.queryParser.QueryParser;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.Query;
+
+import org.hibernate.Transaction;
+import org.hibernate.search.FullTextSession;
+import org.hibernate.search.Search;
+import org.hibernate.search.test.SearchTestCase;
+
+/**
+ * @author John Griffin
+ */
+public class FieldBoostTest extends SearchTestCase {
+
+	public void testBoostedGetDesc() throws Exception {
+		FullTextSession fullTextSession = Search.getFullTextSession( openSession() );
+		buildBoostedGetIndex( fullTextSession );
+
+		fullTextSession.clear();
+		Transaction tx = fullTextSession.beginTransaction();
+
+		QueryParser authorParser = new QueryParser( "author", new StandardAnalyzer() );
+		QueryParser descParser = new QueryParser( "description", new StandardAnalyzer() );
+		Query author = authorParser.parse( "Wells" );
+		Query desc = descParser.parse( "martians" );
+
+		BooleanQuery query = new BooleanQuery();
+		query.add( author, BooleanClause.Occur.SHOULD );
+		query.add( desc, BooleanClause.Occur.SHOULD );
+		//System.out.println( query.toString() );
+
+		org.hibernate.search.FullTextQuery hibQuery =
+				fullTextSession.createFullTextQuery( query, BoostedGetDescriptionLibrary.class );
+		List results = hibQuery.list();
+
+		//System.out.println( hibQuery.explain( 0 ) );
+		//System.out.println( hibQuery.explain( 1 ) );
+
+		assertTrue(
+				"incorrect document returned",
+				( ( BoostedGetDescriptionLibrary ) results.get( 0 ) ).getDescription().startsWith( "Martians" )
+		);
+
+		//cleanup
+		for ( Object element : fullTextSession.createQuery( "from " + BoostedGetDescriptionLibrary.class.getName() )
+				.list() ) {
+			fullTextSession.delete( element );
+		}
+		tx.commit();
+		fullTextSession.close();
+	}
+
+	public void testBoostedFieldDesc() throws Exception {
+		FullTextSession fullTextSession = Search.getFullTextSession( openSession() );
+		buildBoostedFieldIndex( fullTextSession );
+
+		fullTextSession.clear();
+		Transaction tx = fullTextSession.beginTransaction();
+
+		QueryParser authorParser = new QueryParser( "author", new StandardAnalyzer() );
+		QueryParser descParser = new QueryParser( "description", new StandardAnalyzer() );
+		Query author = authorParser.parse( "Wells" );
+		Query desc = descParser.parse( "martians" );
+
+		BooleanQuery query = new BooleanQuery();
+		query.add( author, BooleanClause.Occur.SHOULD );
+		query.add( desc, BooleanClause.Occur.SHOULD );
+		//System.out.println( query.toString() );
+
+		org.hibernate.search.FullTextQuery hibQuery =
+				fullTextSession.createFullTextQuery( query, BoostedFieldDescriptionLibrary.class );
+		List results = hibQuery.list();
+
+		assertTrue(
+				"incorrect document boost",
+				( ( BoostedFieldDescriptionLibrary ) results.get( 0 ) ).getDescription().startsWith( "Martians" )
+		);
+
+		//System.out.println( hibQuery.explain( 0 ) );
+		//System.out.println( hibQuery.explain( 1 ) );
+
+		//cleanup
+		for ( Object element : fullTextSession.createQuery( "from " + BoostedFieldDescriptionLibrary.class.getName() )
+				.list() ) {
+			fullTextSession.delete( element );
+		}
+		tx.commit();
+		fullTextSession.close();
+	}
+
+	public void testBoostedDesc() throws Exception {
+		FullTextSession fullTextSession = Search.getFullTextSession( openSession() );
+		buildBoostedDescIndex( fullTextSession );
+
+		fullTextSession.clear();
+		Transaction tx = fullTextSession.beginTransaction();
+
+		QueryParser authorParser = new QueryParser( "author", new StandardAnalyzer() );
+		QueryParser descParser = new QueryParser( "description", new StandardAnalyzer() );
+		Query author = authorParser.parse( "Wells" );
+		Query desc = descParser.parse( "martians" );
+
+		BooleanQuery query = new BooleanQuery();
+		query.add( author, BooleanClause.Occur.SHOULD );
+		query.add( desc, BooleanClause.Occur.SHOULD );
+		//System.out.println( query.toString() );
+
+		org.hibernate.search.FullTextQuery hibQuery =
+				fullTextSession.createFullTextQuery( query, BoostedDescriptionLibrary.class );
+		List results = hibQuery.list();
+
+		//System.out.println( hibQuery.explain( 0 ) );
+		//System.out.println( hibQuery.explain( 1 ) );
+
+		assertTrue(
+				"incorrect document returned",
+				( ( BoostedDescriptionLibrary ) results.get( 0 ) ).getDescription().startsWith( "Martians" )
+		);
+
+		//cleanup
+		for ( Object element : fullTextSession.createQuery( "from " + BoostedDescriptionLibrary.class.getName() )
+				.list() ) {
+			fullTextSession.delete( element );
+		}
+		tx.commit();
+		fullTextSession.close();
+	}
+
+	private void buildBoostedDescIndex(FullTextSession session) {
+		Transaction tx = session.beginTransaction();
+		BoostedDescriptionLibrary l = new BoostedDescriptionLibrary();
+		l.setAuthor( "H.G. Wells" );
+		l.setTitle( "The Invisible Man" );
+		l.setDescription( "Scientist discovers invisibility and becomes insane." );
+		session.save( l );
+
+		session.save( l );
+		l = new BoostedDescriptionLibrary();
+		l.setAuthor( "H.G. Wells" );
+		l.setTitle( "War of the Worlds" );
+		l.setDescription( "Martians invade earth to eliminate mankind." );
+		session.save( l );
+
+		tx.commit();
+	}
+
+	private void buildBoostedFieldIndex(FullTextSession session) {
+		Transaction tx = session.beginTransaction();
+		BoostedFieldDescriptionLibrary l = new BoostedFieldDescriptionLibrary();
+		l.setAuthor( "H.G. Wells" );
+		l.setTitle( "The Invisible Man" );
+		l.setDescription( "Scientist discovers invisibility and becomes insane." );
+		session.save( l );
+
+		session.save( l );
+		l = new BoostedFieldDescriptionLibrary();
+		l.setAuthor( "H.G. Wells" );
+		l.setTitle( "War of the Worlds" );
+		l.setDescription( "Martians invade earth to eliminate mankind." );
+		session.save( l );
+
+		tx.commit();
+	}
+
+	private void buildBoostedGetIndex(FullTextSession session) {
+		Transaction tx = session.beginTransaction();
+		BoostedGetDescriptionLibrary l = new BoostedGetDescriptionLibrary();
+		l.setAuthor( "H.G. Wells" );
+		l.setTitle( "The Invisible Man" );
+		l.setDescription( "Scientist discovers invisibility and becomes insane." );
+		session.save( l );
+
+		session.save( l );
+		l = new BoostedGetDescriptionLibrary();
+		l.setAuthor( "H.G. Wells" );
+		l.setTitle( "War of the Worlds" );
+		l.setDescription( "Martians invade earth to eliminate mankind." );
+		session.save( l );
+
+		tx.commit();
+	}
+
+	protected Class[] getMappings() {
+		return new Class[] {
+				BoostedDescriptionLibrary.class,
+				BoostedFieldDescriptionLibrary.class,
+				BoostedGetDescriptionLibrary.class,
+		};
+	}
+}

Added: search/trunk/src/test/org/hibernate/search/test/query/boost/Library.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/query/boost/Library.java	                        (rev 0)
+++ search/trunk/src/test/org/hibernate/search/test/query/boost/Library.java	2008-10-24 17:42:28 UTC (rev 15389)
@@ -0,0 +1,61 @@
+package org.hibernate.search.test.query.boost;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+import org.hibernate.search.annotations.DocumentId;
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.Index;
+import org.hibernate.search.annotations.Indexed;
+import org.hibernate.search.annotations.Store;
+
+/**
+ * @author John Griffin
+ */
+ at Entity
+ at Indexed
+public class Library {
+	private int id;
+	private String title;
+	private String author;
+	private String Description;
+
+	@Id
+	@GeneratedValue
+	@DocumentId
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	@Field(store = Store.YES, index = Index.TOKENIZED)
+	public String getTitle() {
+		return title;
+	}
+
+	public void setTitle(String title) {
+		this.title = title;
+	}
+
+	@Field(store = Store.YES, index = Index.TOKENIZED)
+	public String getAuthor() {
+		return author;
+	}
+
+	public void setAuthor(String author) {
+		this.author = author;
+	}
+
+	@Field(store = Store.YES, index = Index.TOKENIZED)
+	public String getDescription() {
+		return Description;
+	}
+
+	public void setDescription(String description) {
+		Description = description;
+	}
+}
\ No newline at end of file




More information about the hibernate-commits mailing list