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
+ */
+(a)Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD })
+@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
+ */
+@Entity
+@Indexed
+@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