[hibernate-commits] Hibernate SVN: r16586 - in search/trunk/src: main/java/org/hibernate/search/engine and 1 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Mon May 18 09:18:59 EDT 2009


Author: hardy.ferentschik
Date: 2009-05-18 09:18:59 -0400 (Mon, 18 May 2009)
New Revision: 16586

Added:
   search/trunk/src/main/java/org/hibernate/search/annotations/DynamicBoost.java
   search/trunk/src/main/java/org/hibernate/search/engine/BoostStrategy.java
   search/trunk/src/main/java/org/hibernate/search/engine/DefaultBoostStrategy.java
   search/trunk/src/test/java/org/hibernate/search/test/query/boost/CustomBoostStrategy.java
   search/trunk/src/test/java/org/hibernate/search/test/query/boost/CustomFieldBoostStrategy.java
   search/trunk/src/test/java/org/hibernate/search/test/query/boost/DynamicBoostedDescriptionLibrary.java
   search/trunk/src/test/java/org/hibernate/search/test/query/boost/DynamicBoostingTest.java
Modified:
   search/trunk/src/main/java/org/hibernate/search/engine/DocumentBuilderContainedEntity.java
   search/trunk/src/main/java/org/hibernate/search/engine/DocumentBuilderIndexedEntity.java
   search/trunk/src/test/java/org/hibernate/search/test/query/boost/FieldBoostTest.java
Log:
HSEARCH-324
Added a first cut for dynamic boosting using the new DynamicBoost annotation. Needs still documentation.

Added: search/trunk/src/main/java/org/hibernate/search/annotations/DynamicBoost.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/annotations/DynamicBoost.java	                        (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/annotations/DynamicBoost.java	2009-05-18 13:18:59 UTC (rev 16586)
@@ -0,0 +1,29 @@
+//$Id$
+package org.hibernate.search.annotations;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.hibernate.search.engine.BoostStrategy;
+
+/**
+ * Apply a dynamic boost factor on a field or a whole entity.
+ *
+ * @author Hardy Ferentschik
+ */
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD })
+ at Documented
+public @interface DynamicBoost {
+
+	/**
+	 * @return An implementation of <code>BoostStrategy</code> to apply a boost
+	 *         value as function of the annotated object.
+	 *
+	 * @see org.hibernate.search.engine.BoostStrategy
+	 */
+	public abstract Class<? extends BoostStrategy> impl();
+}
\ No newline at end of file


Property changes on: search/trunk/src/main/java/org/hibernate/search/annotations/DynamicBoost.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: search/trunk/src/main/java/org/hibernate/search/engine/BoostStrategy.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/engine/BoostStrategy.java	                        (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/engine/BoostStrategy.java	2009-05-18 13:18:59 UTC (rev 16586)
@@ -0,0 +1,13 @@
+package org.hibernate.search.engine;
+
+/**
+ * Interface to implement boost values as functions
+ * of the object value being boosted.
+ * Implementations must be threadsafe.
+ *
+ * @author Hardy Ferentschik
+ * @see org.hibernate.search.annotations.Boost
+ */
+public interface BoostStrategy {
+	public float defineBoost(Object value);
+}


Property changes on: search/trunk/src/main/java/org/hibernate/search/engine/BoostStrategy.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: search/trunk/src/main/java/org/hibernate/search/engine/DefaultBoostStrategy.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/engine/DefaultBoostStrategy.java	                        (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/engine/DefaultBoostStrategy.java	2009-05-18 13:18:59 UTC (rev 16586)
@@ -0,0 +1,28 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed 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.hibernate.search.engine;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class DefaultBoostStrategy implements BoostStrategy {
+
+	public float defineBoost(Object value) {
+		return 1.0f;
+	}
+}


Property changes on: search/trunk/src/main/java/org/hibernate/search/engine/DefaultBoostStrategy.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Modified: search/trunk/src/main/java/org/hibernate/search/engine/DocumentBuilderContainedEntity.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/engine/DocumentBuilderContainedEntity.java	2009-05-18 13:17:55 UTC (rev 16585)
+++ search/trunk/src/main/java/org/hibernate/search/engine/DocumentBuilderContainedEntity.java	2009-05-18 13:18:59 UTC (rev 16586)
@@ -24,7 +24,6 @@
 import org.hibernate.annotations.common.reflection.XClass;
 import org.hibernate.annotations.common.reflection.XMember;
 import org.hibernate.annotations.common.reflection.XProperty;
-import org.hibernate.util.StringHelper;
 import org.hibernate.search.SearchException;
 import org.hibernate.search.analyzer.Discriminator;
 import org.hibernate.search.annotations.AnalyzerDef;
@@ -35,6 +34,7 @@
 import org.hibernate.search.annotations.ClassBridges;
 import org.hibernate.search.annotations.ContainedIn;
 import org.hibernate.search.annotations.DocumentId;
+import org.hibernate.search.annotations.DynamicBoost;
 import org.hibernate.search.annotations.Index;
 import org.hibernate.search.annotations.IndexedEmbedded;
 import org.hibernate.search.annotations.Store;
@@ -48,6 +48,7 @@
 import org.hibernate.search.util.LoggerFactory;
 import org.hibernate.search.util.ReflectionHelper;
 import org.hibernate.search.util.ScopedAnalyzer;
+import org.hibernate.util.StringHelper;
 
 /**
  * Set up and provide a manager for classes which are indexed via <code>@IndexedEmbedded</code>, but themselves do not
@@ -99,6 +100,7 @@
 
 	protected void init(XClass clazz, InitContext context) {
 		metadata.boost = getBoost( clazz );
+		metadata.classBoostStrategy = getDynamicBoost( clazz );
 		metadata.analyzer = context.getDefaultAnalyzer();
 
 		Set<XClass> processedClasses = new HashSet<XClass>();
@@ -195,9 +197,6 @@
 		}
 	}
 
-	/**
-	 * Check for field and method level annotations.
-	 */
 	protected void initializeMemberLevelAnnotations(XProperty member, PropertiesMetadata propertiesMetadata, boolean isRoot,
 													String prefix, Set<XClass> processedClasses, InitContext context) {
 		checkDocumentId( member, propertiesMetadata, isRoot, prefix, context );
@@ -264,7 +263,7 @@
 						"Multiple AnalyzerDiscriminator defined in the same class hierarchy: " + beanClass.getName()
 				);
 			}
-						
+
 			Class<? extends Discriminator> discriminatorClass = discriminiatorAnn.impl();
 			try {
 				propertiesMetadata.discriminator = discriminatorClass.newInstance();
@@ -461,6 +460,7 @@
 		propertiesMetadata.fieldStore.add( getStore( fieldAnn.store() ) );
 		propertiesMetadata.fieldIndex.add( getIndex( fieldAnn.index() ) );
 		propertiesMetadata.fieldBoosts.add( getBoost( member, fieldAnn ) );
+		propertiesMetadata.dynamicFieldBoosts.add( getDynamicBoost( member ) );
 		propertiesMetadata.fieldTermVectors.add( getTermVector( fieldAnn.termVector() ) );
 		propertiesMetadata.fieldBridges.add( BridgeFactory.guessType( fieldAnn, member, reflectionManager ) );
 
@@ -486,6 +486,25 @@
 		return computedBoost;
 	}
 
+	protected BoostStrategy getDynamicBoost(XProperty member) {
+		DynamicBoost boostAnnotation = member.getAnnotation( DynamicBoost.class );
+		if ( boostAnnotation == null ) {
+			return new DefaultBoostStrategy();
+		}
+
+		Class<? extends BoostStrategy> boostStrategyClass = boostAnnotation.impl();
+		BoostStrategy strategy;
+		try {
+			strategy = boostStrategyClass.newInstance();
+		}
+		catch ( Exception e ) {
+			throw new SearchException(
+					"Unable to instantiate boost strategy implementation: " + boostStrategyClass.getName()
+			);
+		}
+		return strategy;
+	}
+
 	private String buildEmbeddedPrefix(String prefix, IndexedEmbedded embeddedAnn, XProperty member) {
 		String localPrefix = prefix;
 		if ( ".".equals( embeddedAnn.prefix() ) ) {
@@ -544,15 +563,40 @@
 	}
 
 	protected Float getBoost(XClass element) {
+		float boost = 1.0f;
 		if ( element == null ) {
+			return boost;
+		}
+		Boost boostAnnotation = element.getAnnotation( Boost.class );
+		if ( boostAnnotation != null ) {
+			boost = boostAnnotation.value();
+		}
+		return boost;
+	}
+
+	protected BoostStrategy getDynamicBoost(XClass element) {
+		if ( element == null ) {
 			return null;
 		}
-		Boost boost = element.getAnnotation( Boost.class );
-		return boost != null ?
-				boost.value() :
-				null;
+		DynamicBoost boostAnnotation = element.getAnnotation( DynamicBoost.class );
+		if ( boostAnnotation == null ) {
+			return new DefaultBoostStrategy();
+		}
+
+		Class<? extends BoostStrategy> boostStrategyClass = boostAnnotation.impl();
+		BoostStrategy strategy;
+		try {
+			strategy = boostStrategyClass.newInstance();
+		}
+		catch ( Exception e ) {
+			throw new SearchException(
+					"Unable to instantiate boost strategy implementation: " + boostStrategyClass.getName()
+			);
+		}
+		return strategy;
 	}
 
+
 	//TODO could we use T instead of EntityClass?
 	public void addWorkToQueue(Class<T> entityClass, T entity, Serializable id, WorkType workType, List<LuceneWork> queue, SearchFactoryImplementor searchFactoryImplementor) {
 		/**
@@ -673,24 +717,31 @@
 	}
 
 	/**
-	 * Wrapper class containing all the meta data extracted out of the entities.
+	 * Wrapper class containing all the meta data extracted out of a single entity.
+	 * All field/property related properties are kept in lists. Retrieving all metadata for a given
+	 * property/field means accessing all the lists with the same index.
 	 */
 	protected static class PropertiesMetadata {
-		public Float boost;
+		public float boost;
 		public Analyzer analyzer;
 		public Discriminator discriminator;
 		public XMember discriminatorGetter;
+		public BoostStrategy classBoostStrategy;
+		
 		public final List<String> fieldNames = new ArrayList<String>();
 		public final List<XMember> fieldGetters = new ArrayList<XMember>();
 		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<BoostStrategy> dynamicFieldBoosts = new ArrayList<BoostStrategy>();
+
 		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>();
 		public final List<Container> embeddedContainers = new ArrayList<Container>();
 		public final List<XMember> containedInGetters = new ArrayList<XMember>();
+
 		public final List<String> classNames = new ArrayList<String>();
 		public final List<Field.Store> classStores = new ArrayList<Field.Store>();
 		public final List<Field.Index> classIndexes = new ArrayList<Field.Index>();
@@ -712,13 +763,19 @@
 			);
 		}
 
-		protected LuceneOptions getFieldLuceneOptions(int i) {
+		protected LuceneOptions getFieldLuceneOptions(int i, Object value) {
 			LuceneOptions options;
 			options = new LuceneOptionsImpl(
 					fieldStore.get( i ),
-					fieldIndex.get( i ), fieldTermVectors.get( i ), fieldBoosts.get( i )
+					fieldIndex.get( i ),
+					fieldTermVectors.get( i ),
+					fieldBoosts.get( i ) * dynamicFieldBoosts.get( i ).defineBoost( value )
 			);
 			return options;
 		}
+
+		protected float getClassBoost(Object value) {
+			return boost * classBoostStrategy.defineBoost( value );
+		}
 	}
 }
\ No newline at end of file

Modified: search/trunk/src/main/java/org/hibernate/search/engine/DocumentBuilderIndexedEntity.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/engine/DocumentBuilderIndexedEntity.java	2009-05-18 13:17:55 UTC (rev 16585)
+++ search/trunk/src/main/java/org/hibernate/search/engine/DocumentBuilderIndexedEntity.java	2009-05-18 13:18:59 UTC (rev 16586)
@@ -23,7 +23,6 @@
 import org.hibernate.annotations.common.reflection.XClass;
 import org.hibernate.annotations.common.reflection.XMember;
 import org.hibernate.annotations.common.reflection.XProperty;
-import org.hibernate.util.ReflectHelper;
 import org.hibernate.proxy.HibernateProxy;
 import org.hibernate.search.SearchException;
 import org.hibernate.search.analyzer.Discriminator;
@@ -48,6 +47,7 @@
 import org.hibernate.search.store.IndexShardingStrategy;
 import org.hibernate.search.util.LoggerFactory;
 import org.hibernate.search.util.ReflectionHelper;
+import org.hibernate.util.ReflectHelper;
 
 /**
  * Set up and provide a manager for classes which are directly annotated with <code>@Indexed</code>.
@@ -196,6 +196,7 @@
 				propertiesMetadata.fieldTermVectors.add( getTermVector( TermVector.NO ) );
 				propertiesMetadata.fieldBridges.add( BridgeFactory.guessType( null, member, reflectionManager ) );
 				propertiesMetadata.fieldBoosts.add( getBoost( member, null ) );
+				propertiesMetadata.dynamicFieldBoosts.add( getDynamicBoost( member ) );
 				// property > entity analyzer (no field analyzer)
 				Analyzer analyzer = getAnalyzer( member, context );
 				if ( analyzer == null ) {
@@ -221,28 +222,34 @@
 	 * @return the annotation used as document id or <code>null</code> if id annotation is specified on the property.
 	 */
 	private Annotation getIdAnnotation(XProperty member, InitContext context) {
+		Annotation idAnnotation = null;
+
 		// check for explicit DocumentId
-		Annotation documentIdAnn = member.getAnnotation( DocumentId.class );
+		DocumentId documentIdAnn = member.getAnnotation( DocumentId.class );
 		if ( documentIdAnn != null ) {
 			explicitDocumentId = true;
-			return documentIdAnn;
+			idAnnotation = documentIdAnn;
 		}
-
 		// check for JPA @Id
-		if ( !explicitDocumentId && context.isJpaPresent() ) {
-			Class idClass;
+		else if ( !explicitDocumentId && context.isJpaPresent() ) {
+			Annotation jpaId;
 			try {
-				idClass = org.hibernate.util.ReflectHelper.classForName( "javax.persistence.Id", InitContext.class );
+				@SuppressWarnings("unchecked")
+				Class<? extends Annotation> jpaIdClass = org.hibernate
+						.util
+						.ReflectHelper
+						.classForName( "javax.persistence.Id", InitContext.class );
+				jpaId = member.getAnnotation( jpaIdClass );
 			}
 			catch ( ClassNotFoundException e ) {
 				throw new SearchException( "Unable to load @Id.class even though it should be present ?!" );
 			}
-			documentIdAnn = member.getAnnotation( idClass );
-			if ( documentIdAnn != null ) {
+			if ( jpaId != null ) {
 				log.debug( "Found JPA id and using it as document id" );
+				idAnnotation = jpaId;
 			}
 		}
-		return documentIdAnn;
+		return idAnnotation;
 	}
 
 	private ProvidedId findProvidedId(XClass clazz, ReflectionManager reflectionManager) {
@@ -258,7 +265,7 @@
 	//TODO could we use T instead of EntityClass?
 	public void addWorkToQueue(Class<T> entityClass, T entity, Serializable id, WorkType workType, List<LuceneWork> queue, SearchFactoryImplementor searchFactoryImplementor) {
 		//TODO with the caller loop we are in a n^2: optimize it using a HashMap for work recognition
-		
+
 		boolean sameIdWasSetToBeDeleted = false;
 		List<LuceneWork> toDelete = new ArrayList<LuceneWork>();
 		boolean duplicateDelete = false;
@@ -301,7 +308,7 @@
 			//avoid updating (and thus adding) objects which are going to be deleted
 			return;
 		}
-		
+
 		for ( LuceneWork luceneWork : toDelete ) {
 			queue.remove( luceneWork );
 		}
@@ -367,9 +374,7 @@
 
 		Document doc = new Document();
 		final Class<?> entityType = Hibernate.getClass( instance );
-		if ( metadata.boost != null ) {
-			doc.setBoost( metadata.boost );
-		}
+		doc.setBoost( metadata.getClassBoost( instance ) );
 
 		// add the class name of the entity to the document
 		Field classField =
@@ -419,7 +424,7 @@
 			Object value = ReflectionHelper.getMemberValue( unproxiedInstance, member );
 			propertiesMetadata.fieldBridges.get( i ).set(
 					propertiesMetadata.fieldNames.get( i ), value, doc,
-					propertiesMetadata.getFieldLuceneOptions( i )
+					propertiesMetadata.getFieldLuceneOptions( i, value )
 			);
 		}
 

Added: search/trunk/src/test/java/org/hibernate/search/test/query/boost/CustomBoostStrategy.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/query/boost/CustomBoostStrategy.java	                        (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/query/boost/CustomBoostStrategy.java	2009-05-18 13:18:59 UTC (rev 16586)
@@ -0,0 +1,19 @@
+//$Id$
+package org.hibernate.search.test.query.boost;
+
+import org.hibernate.search.engine.BoostStrategy;
+
+/**
+ * Example for a custom <code>BoostStrategy</code> implementation.
+ *
+ * @author Sanne Grinovero
+ * @author Hardy Ferentschik
+ * @see org.hibernate.search.engine.BoostStrategy
+ */
+public class CustomBoostStrategy implements BoostStrategy {
+
+	public float defineBoost(Object value) {
+		DynamicBoostedDescriptionLibrary indexed = ( DynamicBoostedDescriptionLibrary ) value;
+		return indexed.getDynScore();
+	}
+}


Property changes on: search/trunk/src/test/java/org/hibernate/search/test/query/boost/CustomBoostStrategy.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: search/trunk/src/test/java/org/hibernate/search/test/query/boost/CustomFieldBoostStrategy.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/query/boost/CustomFieldBoostStrategy.java	                        (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/query/boost/CustomFieldBoostStrategy.java	2009-05-18 13:18:59 UTC (rev 16586)
@@ -0,0 +1,23 @@
+//$Id$
+package org.hibernate.search.test.query.boost;
+
+import org.hibernate.search.engine.BoostStrategy;
+
+/**
+ * Example for a custom <code>BoostStrategy</code> implementation.
+ *
+ * @author Hardy Ferentschik
+ * @see org.hibernate.search.engine.BoostStrategy
+ */
+public class CustomFieldBoostStrategy implements BoostStrategy {
+
+	public float defineBoost(Object value) {
+		String name = ( String ) value;
+		if ( "foobar".equals( name ) ) {
+			return 3.0f;
+		}
+		else {
+			return 1.0f;
+		}
+	}
+}
\ No newline at end of file


Property changes on: search/trunk/src/test/java/org/hibernate/search/test/query/boost/CustomFieldBoostStrategy.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: search/trunk/src/test/java/org/hibernate/search/test/query/boost/DynamicBoostedDescriptionLibrary.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/query/boost/DynamicBoostedDescriptionLibrary.java	                        (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/query/boost/DynamicBoostedDescriptionLibrary.java	2009-05-18 13:18:59 UTC (rev 16586)
@@ -0,0 +1,63 @@
+//$Id$
+package org.hibernate.search.test.query.boost;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+import org.hibernate.search.annotations.Boost;
+import org.hibernate.search.annotations.DocumentId;
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.Indexed;
+import org.hibernate.search.annotations.Store;
+import org.hibernate.search.annotations.DynamicBoost;
+
+/**
+ * Test entity using a custom <code>CustomBoostStrategy</code> to set
+ * the document boost as the dynScore field.
+ *
+ * @author Sanne Grinovero
+ * @author Hardy Ferentschik
+ */
+ at Entity
+ at Indexed
+ at DynamicBoost(impl = CustomBoostStrategy.class)
+public class DynamicBoostedDescriptionLibrary {
+
+	private int id;
+	private float dynScore;
+	private String name;
+
+	public DynamicBoostedDescriptionLibrary() {
+		dynScore = 1.0f;
+	}
+
+	@Id
+	@GeneratedValue
+	@DocumentId
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public float getDynScore() {
+		return dynScore;
+	}
+
+	public void setDynScore(float dynScore) {
+		this.dynScore = dynScore;
+	}
+
+	@Field(store = Store.YES)
+	@DynamicBoost(impl = CustomFieldBoostStrategy.class)
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+}


Property changes on: search/trunk/src/test/java/org/hibernate/search/test/query/boost/DynamicBoostedDescriptionLibrary.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: search/trunk/src/test/java/org/hibernate/search/test/query/boost/DynamicBoostingTest.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/query/boost/DynamicBoostingTest.java	                        (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/query/boost/DynamicBoostingTest.java	2009-05-18 13:18:59 UTC (rev 16586)
@@ -0,0 +1,109 @@
+//$Id$
+package org.hibernate.search.test.query.boost;
+
+import java.util.List;
+
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.TermQuery;
+import org.slf4j.Logger;
+
+import org.hibernate.Session;
+import org.hibernate.search.FullTextSession;
+import org.hibernate.search.ProjectionConstants;
+import org.hibernate.search.Search;
+import org.hibernate.search.test.SearchTestCase;
+import org.hibernate.search.util.LoggerFactory;
+
+public class DynamicBoostingTest extends SearchTestCase {
+
+	private static final Logger log = LoggerFactory.make();
+
+	public void testDynamicBoosts() throws Exception {
+
+		Session session = openSession();
+		session.beginTransaction();
+
+		DynamicBoostedDescriptionLibrary lib1 = new DynamicBoostedDescriptionLibrary();
+		lib1.setName( "one" );
+		session.persist( lib1 );
+
+		DynamicBoostedDescriptionLibrary lib2 = new DynamicBoostedDescriptionLibrary();
+		lib2.setName( "two" );
+		session.persist( lib2 );
+
+		session.getTransaction().commit();
+		session.close();
+
+		float lib1Score = getScore( new TermQuery( new Term( "name", "one" ) ) );
+		float lib2Score = getScore( new TermQuery( new Term( "name", "two" ) ) );
+		assertEquals( "The scores should be equal", lib1Score, lib2Score );
+
+		// set dynamic score and reindex!
+		session = openSession();
+		session.beginTransaction();
+
+		session.refresh( lib2 );
+		lib2.setDynScore( 2.0f );
+
+		session.getTransaction().commit();
+		session.close();
+
+		lib1Score = getScore( new TermQuery( new Term( "name", "one" ) ) );
+		lib2Score = getScore( new TermQuery( new Term( "name", "two" ) ) );
+		assertTrue( "lib2score should be greater than lib1score", lib1Score < lib2Score );
+
+
+
+		lib1Score = getScore( new TermQuery( new Term( "name", "foobar" ) ) );
+		assertEquals( "lib1score should be 0 since term is not yet indexed.", 0.0f, lib1Score );
+
+		// index foobar
+		session = openSession();
+		session.beginTransaction();
+
+		session.refresh( lib1 );
+		lib1.setName( "foobar" );
+
+		session.getTransaction().commit();
+		session.close();
+
+		lib1Score = getScore( new TermQuery( new Term( "name", "foobar" ) ) );
+		lib2Score = getScore( new TermQuery( new Term( "name", "two" ) ) );
+		assertTrue( "lib1score should be greater than lib2score", lib1Score > lib2Score );
+	}
+
+	private float getScore(Query query) {
+		Session session = openSession();
+		Object[] queryResult;
+		float score;
+		try {
+			FullTextSession fullTextSession = Search.getFullTextSession( session );
+			List resultList = fullTextSession
+					.createFullTextQuery( query, DynamicBoostedDescriptionLibrary.class )
+					.setProjection( ProjectionConstants.SCORE, ProjectionConstants.EXPLANATION )
+					.setMaxResults( 1 )
+					.list();
+
+			if ( resultList.size() == 0 ) {
+				score = 0.0f;
+			}
+			else {
+				queryResult = ( Object[] ) resultList.get( 0 );
+				score = ( Float ) queryResult[0];
+				String explanation = queryResult[1].toString();
+				log.debug( "score: " + score + " explanation: " + explanation );
+			}
+		}
+		finally {
+			session.close();
+		}
+		return score;
+	}
+
+	protected Class[] getMappings() {
+		return new Class[] {
+				DynamicBoostedDescriptionLibrary.class
+		};
+	}
+}


Property changes on: search/trunk/src/test/java/org/hibernate/search/test/query/boost/DynamicBoostingTest.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Modified: search/trunk/src/test/java/org/hibernate/search/test/query/boost/FieldBoostTest.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/query/boost/FieldBoostTest.java	2009-05-18 13:17:55 UTC (rev 16585)
+++ search/trunk/src/test/java/org/hibernate/search/test/query/boost/FieldBoostTest.java	2009-05-18 13:18:59 UTC (rev 16586)
@@ -1,3 +1,4 @@
+//$Id$
 package org.hibernate.search.test.query.boost;
 
 import java.util.List;
@@ -7,17 +8,21 @@
 import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.Query;
+import org.slf4j.Logger;
 
 import org.hibernate.Transaction;
 import org.hibernate.search.FullTextSession;
 import org.hibernate.search.Search;
 import org.hibernate.search.test.SearchTestCase;
+import org.hibernate.search.util.LoggerFactory;
 
 /**
  * @author John Griffin
  */
-public class FieldBoostTest extends SearchTestCase {
+public class  FieldBoostTest extends SearchTestCase {
 
+	private static final Logger log = LoggerFactory.make();
+
 	public void testBoostedGetDesc() throws Exception {
 		FullTextSession fullTextSession = Search.getFullTextSession( openSession() );
 		buildBoostedGetIndex( fullTextSession );
@@ -33,14 +38,14 @@
 		BooleanQuery query = new BooleanQuery();
 		query.add( author, BooleanClause.Occur.SHOULD );
 		query.add( desc, BooleanClause.Occur.SHOULD );
-		//System.out.println( query.toString() );
+		log.debug( 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 ) );
+		log.debug( hibQuery.explain( 0 ).toString() );
+		log.debug( hibQuery.explain( 1 ).toString() );
 
 		assertTrue(
 				"incorrect document returned",
@@ -71,7 +76,7 @@
 		BooleanQuery query = new BooleanQuery();
 		query.add( author, BooleanClause.Occur.SHOULD );
 		query.add( desc, BooleanClause.Occur.SHOULD );
-		//System.out.println( query.toString() );
+		log.debug( query.toString() );
 
 		org.hibernate.search.FullTextQuery hibQuery =
 				fullTextSession.createFullTextQuery( query, BoostedFieldDescriptionLibrary.class );
@@ -82,8 +87,8 @@
 				( ( BoostedFieldDescriptionLibrary ) results.get( 0 ) ).getDescription().startsWith( "Martians" )
 		);
 
-		//System.out.println( hibQuery.explain( 0 ) );
-		//System.out.println( hibQuery.explain( 1 ) );
+		log.debug( hibQuery.explain( 0 ).toString() );
+		log.debug( hibQuery.explain( 1 ).toString() );
 
 		//cleanup
 		for ( Object element : fullTextSession.createQuery( "from " + BoostedFieldDescriptionLibrary.class.getName() )
@@ -109,14 +114,14 @@
 		BooleanQuery query = new BooleanQuery();
 		query.add( author, BooleanClause.Occur.SHOULD );
 		query.add( desc, BooleanClause.Occur.SHOULD );
-		//System.out.println( query.toString() );
+		log.debug( 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 ) );
+		log.debug( hibQuery.explain( 0 ).toString() );
+		log.debug( hibQuery.explain( 1 ).toString() );
 
 		assertTrue(
 				"incorrect document returned",


Property changes on: search/trunk/src/test/java/org/hibernate/search/test/query/boost/FieldBoostTest.java
___________________________________________________________________
Name: svn:keywords
   + Id




More information about the hibernate-commits mailing list