You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ho...@apache.org on 2015/11/23 17:50:49 UTC

svn commit: r1715881 - in /lucene/dev/trunk/solr: ./ core/src/java/org/apache/solr/search/similarities/ core/src/test-files/solr/collection1/conf/ core/src/test/org/apache/solr/schema/ core/src/test/org/apache/solr/search/similarities/

Author: hossman
Date: Mon Nov 23 16:50:49 2015
New Revision: 1715881

URL: http://svn.apache.org/viewvc?rev=1715881&view=rev
Log:
SOLR-8329: SchemaSimilarityFactory now supports a 'defaultSimFromFieldType' init option for using a fieldType name to identify which Similarity to use as a default

Added:
    lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/bad-schema-sim-default-does-not-exist.xml
      - copied, changed from r1715393, lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/bad-schema-sim-global-vs-ft-mismatch.xml
    lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/bad-schema-sim-default-has-no-explicit-sim.xml
      - copied, changed from r1715393, lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/bad-schema-sim-global-vs-ft-mismatch.xml
    lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/schema-sim-default-override.xml
      - copied, changed from r1715393, lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/schema-sim.xml
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/similarities/TestPerFieldSimilarityWithDefaultOverride.java
      - copied, changed from r1715381, lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/similarities/TestPerFieldSimilarity.java
Modified:
    lucene/dev/trunk/solr/CHANGES.txt
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/similarities/SchemaSimilarityFactory.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/BadIndexSchemaTest.java

Modified: lucene/dev/trunk/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/CHANGES.txt?rev=1715881&r1=1715880&r2=1715881&view=diff
==============================================================================
--- lucene/dev/trunk/solr/CHANGES.txt (original)
+++ lucene/dev/trunk/solr/CHANGES.txt Mon Nov 23 16:50:49 2015
@@ -242,6 +242,9 @@ New Features
 * SOLR-6168: Add a 'sort' local param to the collapse QParser to support using complex sort options
   to select the representitive doc for each collapsed group. (Umesh Prasad, hossman)
 
+* SOLR-8329: SchemaSimilarityFactory now supports a 'defaultSimFromFieldType' init option for using
+  a fieldType name to identify which Similarity to use as a default. (hossman)
+
 Bug Fixes
 ----------------------
 

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/similarities/SchemaSimilarityFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/similarities/SchemaSimilarityFactory.java?rev=1715881&r1=1715880&r2=1715881&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/similarities/SchemaSimilarityFactory.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/similarities/SchemaSimilarityFactory.java Mon Nov 23 16:50:49 2015
@@ -23,6 +23,8 @@ import org.apache.lucene.search.similari
 import org.apache.lucene.search.similarities.Similarity;
 import org.apache.lucene.util.Version;
 
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.SolrException.ErrorCode;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.schema.FieldType;
@@ -34,55 +36,72 @@ import org.slf4j.LoggerFactory;
 
 /**
  * <p>
- * SimilarityFactory that returns a {@link PerFieldSimilarityWrapper}
- * that delegates to the field type, if it's configured, otherwise
- * returns a sensible default depending on the {@link Version} matching configured.
+ * <code>SimilarityFactory</code> that returns a global {@link PerFieldSimilarityWrapper}
+ * that delegates to the field type, if it's configured.  For field type's that
+ * do not have a <code>Similarity</code> explicitly configured, the global <code>Similarity</code> 
+ * will use per fieldtype defaults -- either based on an explicitly configured 
+ * <code>defaultSimFromFieldType</code> a sensible default depending on the {@link Version} 
+ * matching configured:
  * </p>
  * <ul>
  *  <li><code>luceneMatchVersion &lt; 6.0</code> = {@link ClassicSimilarity}</li>
  *  <li><code>luceneMatchVersion &gt;= 6.0</code> = {@link BM25Similarity}</li>
  * </ul>
  * <p>
- * <b>NOTE:</b> Users should be aware that in addition to supporting 
- * <code>Similarity</code> configurations specified on individual 
- * field types, this factory also differs in behavior from 
- * {@link ClassicSimilarityFactory} because of other differences in the 
- * implementations of <code>PerFieldSimilarityWrapper</code> and 
- * {@link ClassicSimilarity} - notably in methods such as 
- * {@link Similarity#coord} and {@link Similarity#queryNorm}.  
+ * The <code>defaultSimFromFieldType</code> option accepts the name of any fieldtype, and uses 
+ * whatever <code>Similarity</code> is explicitly configured for that fieldType as thedefault for 
+ * all other field types.  For example:
+ * </p>
+ * <pre class="prettyprint">
+ *   &lt;similarity class="solr.SchemaSimilarityFactory" &gt;
+ *     &lt;str name="defaultSimFromFieldType"&gt;type-using-custom-dfr&lt;/str&gt;
+ *   &lt;/similarity&gt;
+ *   ...
+ *   &lt;fieldType name="type-using-custom-dfr" class="solr.TextField"&gt;
+ *     ...
+ *     &lt;similarity class="solr.DFRSimilarityFactory"&gt;
+ *       &lt;str name="basicModel"&gt;I(F)&lt;/str&gt;
+ *       &lt;str name="afterEffect"&gt;B&lt;/str&gt;
+ *       &lt;str name="normalization"&gt;H3&lt;/str&gt;
+ *       &lt;float name="mu"&gt;900&lt;/float&gt;
+ *     &lt;/similarity&gt;
+ *   &lt;/fieldType&gt;
+ * </pre>
+ * <p>
+ * In the example above, any fieldtypes that do not define their own <code>&lt;/similarity/&gt;</code> 
+ * will use the <code>Similarity</code> configured for the <code>type-using-custom-dfr</code>.
+ * </p>
+ * 
+ * <p>
+ * <b>NOTE:</b> Users should be aware that even when this factory uses a single default 
+ * <code>Similarity</code> for some or all fields in a Query, the behavior can be inconsistent 
+ * with the behavior of explicitly configuring that same <code>Similarity</code> globally, because 
+ * of differences in how some multi-field / multi-clause behavior is defined in 
+ * <code>PerFieldSimilarityWrapper</code>.  In particular please consider carefully the documentation 
+ * &amp; implementation of {@link Similarity#coord} and {@link Similarity#queryNorm} in 
+ * {@link ClassicSimilarity} compared to {@link PerFieldSimilarityWrapper}
  * </p>
  *
  * @see FieldType#getSimilarity
  */
 public class SchemaSimilarityFactory extends SimilarityFactory implements SolrCoreAware {
+
+  private static final String INIT_OPT = "defaultSimFromFieldType";
+  
+  private String defaultSimFromFieldType; // set by init, if null use sensible implicit default
   
-  private Similarity similarity; // set by init
-  private Similarity defaultSimilarity; // set by inform(SolrCore)
-  private volatile SolrCore core;
+  private volatile SolrCore core; // set by inform(SolrCore)
+  private volatile Similarity similarity; // lazy instantiated
 
   @Override
   public void inform(SolrCore core) {
     this.core = core;
-    this.defaultSimilarity = this.core.getSolrConfig().luceneMatchVersion.onOrAfter(Version.LUCENE_6_0_0)
-      ? new BM25Similarity()
-      : new ClassicSimilarity();
   }
   
   @Override
   public void init(SolrParams args) {
+    defaultSimFromFieldType = args.get(INIT_OPT, null);
     super.init(args);
-    similarity = new PerFieldSimilarityWrapper() {
-      @Override
-      public Similarity get(String name) {
-        FieldType fieldType = core.getLatestSchema().getFieldTypeNoEx(name);
-        if (fieldType == null) {
-          return defaultSimilarity;
-        } else {
-          Similarity similarity = fieldType.getSimilarity();
-          return similarity == null ? defaultSimilarity : similarity;
-        }
-      }
-    };
   }
 
   @Override
@@ -90,6 +109,47 @@ public class SchemaSimilarityFactory ext
     if (null == core) {
       throw new IllegalStateException("SchemaSimilarityFactory can not be used until SolrCoreAware.inform has been called");
     }
+    if (null == similarity) {
+      // Need to instantiate lazily, can't do this in inform(SolrCore) because of chicken/egg
+      // circular initialization hell with core.getLatestSchema() to lookup defaultSimFromFieldType
+      
+      Similarity defaultSim = null;
+      if (null == defaultSimFromFieldType) {
+        // nothing configured, choose a sensible implicit default...
+        defaultSim = this.core.getSolrConfig().luceneMatchVersion.onOrAfter(Version.LUCENE_6_0_0)
+          ? new BM25Similarity()
+          : new ClassicSimilarity();
+      } else {
+        FieldType defSimFT = core.getLatestSchema().getFieldTypeByName(defaultSimFromFieldType);
+        if (null == defSimFT) {
+          throw new SolrException(ErrorCode.SERVER_ERROR,
+                                  "SchemaSimilarityFactory configured with " + INIT_OPT + "='" +
+                                  defaultSimFromFieldType + "' but that <fieldType> does not exist");
+                                  
+        }
+        defaultSim = defSimFT.getSimilarity();
+        if (null == defaultSim) {
+          throw new SolrException(ErrorCode.SERVER_ERROR,
+                                  "SchemaSimilarityFactory configured with " + INIT_OPT + "='" + 
+                                  defaultSimFromFieldType +
+                                  "' but that <fieldType> does not define a <similarity>");
+        }
+      }
+      assert null != defaultSim;
+      final Similarity defaultSimilarity = defaultSim;
+      similarity = new PerFieldSimilarityWrapper() {
+        @Override
+        public Similarity get(String name) {
+          FieldType fieldType = core.getLatestSchema().getFieldTypeNoEx(name);
+          if (fieldType == null) {
+            return defaultSimilarity;
+          } else {
+            Similarity similarity = fieldType.getSimilarity();
+            return similarity == null ? defaultSimilarity : similarity;
+          }
+        }
+      };
+    }
     return similarity;
   }
 }

Copied: lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/bad-schema-sim-default-does-not-exist.xml (from r1715393, lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/bad-schema-sim-global-vs-ft-mismatch.xml)
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/bad-schema-sim-default-does-not-exist.xml?p2=lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/bad-schema-sim-default-does-not-exist.xml&p1=lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/bad-schema-sim-global-vs-ft-mismatch.xml&r1=1715393&r2=1715881&rev=1715881&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/bad-schema-sim-global-vs-ft-mismatch.xml (original)
+++ lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/bad-schema-sim-default-does-not-exist.xml Mon Nov 23 16:50:49 2015
@@ -18,22 +18,25 @@
 
 <schema name="bad-schema-sim-global-vs-ft-mismatch" version="1.0">
 
-  <similarity class="solr.BM25SimilarityFactory" /> <!-- global sim -->
+  <similarity class="solr.SchemaSimilarityFactory" >
+    <!-- BROKEN: the named fieldType does not exist -->
+    <str name="defaultSimFromFieldType">ft-does-not-exist</str>
+  </similarity>
   
-  <types>
-    <fieldType name="sim1" class="solr.TextField">
-      <analyzer>
-        <tokenizer class="solr.MockTokenizerFactory"/>
-      </analyzer>
-      <!-- BAD: similarity here but global sim does not allow it -->
-      <similarity class="org.apache.lucene.misc.SweetSpotSimilarity"/>
-    </fieldType>
- </types>
-
- <fields>
-   <field name="sim1text" type="sim1" indexed="true" stored="true"/>
-   <dynamicField name="*" type="sim1" />
- </fields>
+  <fieldType name="ft-has-no-sim" class="solr.TextField">
+    <analyzer>
+      <tokenizer class="solr.MockTokenizerFactory"/>
+    </analyzer>
+  </fieldType>
+
+  <fieldType name="ft-overrides-default-sim" class="solr.TextField">
+    <analyzer>
+      <tokenizer class="solr.MockTokenizerFactory"/>
+    </analyzer>
+    <similarity class="org.apache.lucene.misc.SweetSpotSimilarity"/>
+  </fieldType>
+
+  <field name="sim1text" type="ft-overrides-default-sim" indexed="true" stored="true"/>
 
  <defaultSearchField>sim1text</defaultSearchField>
 

Copied: lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/bad-schema-sim-default-has-no-explicit-sim.xml (from r1715393, lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/bad-schema-sim-global-vs-ft-mismatch.xml)
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/bad-schema-sim-default-has-no-explicit-sim.xml?p2=lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/bad-schema-sim-default-has-no-explicit-sim.xml&p1=lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/bad-schema-sim-global-vs-ft-mismatch.xml&r1=1715393&r2=1715881&rev=1715881&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/bad-schema-sim-global-vs-ft-mismatch.xml (original)
+++ lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/bad-schema-sim-default-has-no-explicit-sim.xml Mon Nov 23 16:50:49 2015
@@ -18,22 +18,25 @@
 
 <schema name="bad-schema-sim-global-vs-ft-mismatch" version="1.0">
 
-  <similarity class="solr.BM25SimilarityFactory" /> <!-- global sim -->
+  <similarity class="solr.SchemaSimilarityFactory" >
+    <!-- BROKEN: the named fieldType does not have an explicit sim defined, circular default -->
+    <str name="defaultSimFromFieldType">ft-has-no-sim</str>
+  </similarity>
   
-  <types>
-    <fieldType name="sim1" class="solr.TextField">
-      <analyzer>
-        <tokenizer class="solr.MockTokenizerFactory"/>
-      </analyzer>
-      <!-- BAD: similarity here but global sim does not allow it -->
-      <similarity class="org.apache.lucene.misc.SweetSpotSimilarity"/>
-    </fieldType>
- </types>
-
- <fields>
-   <field name="sim1text" type="sim1" indexed="true" stored="true"/>
-   <dynamicField name="*" type="sim1" />
- </fields>
+  <fieldType name="ft-has-no-sim" class="solr.TextField">
+    <analyzer>
+      <tokenizer class="solr.MockTokenizerFactory"/>
+    </analyzer>
+  </fieldType>
+
+  <fieldType name="ft-overrides-default-sim" class="solr.TextField">
+    <analyzer>
+      <tokenizer class="solr.MockTokenizerFactory"/>
+    </analyzer>
+    <similarity class="org.apache.lucene.misc.SweetSpotSimilarity"/>
+  </fieldType>
+
+  <field name="sim1text" type="ft-overrides-default-sim" indexed="true" stored="true"/>
 
  <defaultSearchField>sim1text</defaultSearchField>
 

Copied: lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/schema-sim-default-override.xml (from r1715393, lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/schema-sim.xml)
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/schema-sim-default-override.xml?p2=lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/schema-sim-default-override.xml&p1=lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/schema-sim.xml&r1=1715393&r2=1715881&rev=1715881&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/schema-sim.xml (original)
+++ lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/schema-sim-default-override.xml Mon Nov 23 16:50:49 2015
@@ -16,14 +16,17 @@
  limitations under the License.
 -->
 
-<!-- Per-field similarity example for testing -->
+<!-- Per-field similarity testing where default for fieldtypes w/o sim is overridden -->
 
 <schema name="test" version="1.0">
-  <types>
-  <fieldType name="int" class="solr.TrieIntField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>
+  
+  <similarity class="solr.SchemaSimilarityFactory" >
+    <str name="defaultSimFromFieldType">sim-used-as-default-override</str>
+  </similarity>
+
   <!--  some per-field similarity examples --> 
   <!--  specify a Similarity classname directly -->
-  <fieldType name="sim1" class="solr.TextField">
+  <fieldType name="sim-explicit" class="solr.TextField">
     <analyzer>
       <tokenizer class="solr.MockTokenizerFactory"/>
     </analyzer>
@@ -31,7 +34,7 @@
   </fieldType>
 
   <!--  specify a Similarity factory -->  
-  <fieldType name="sim2" class="solr.TextField">
+  <fieldType name="sim-used-as-default-override" class="solr.TextField">
     <analyzer>
       <tokenizer class="solr.MockTokenizerFactory"/>
     </analyzer>
@@ -41,34 +44,23 @@
   </fieldType>
   
   <!-- don't specify any sim at all: get the default  -->
-  <fieldType name="sim3" class="solr.TextField">
+  <fieldType name="sim-none-get-default" class="solr.TextField">
     <analyzer>
       <tokenizer class="solr.MockTokenizerFactory"/>
     </analyzer>
   </fieldType>
- </types>
 
- <fields>
-   <field name="id" type="int" indexed="true" stored="true" multiValued="false" required="false"/>
-   <field name="sim1text" type="sim1" indexed="true" stored="true"/>
-   <field name="sim2text" type="sim2" indexed="true" stored="true"/>
-   <field name="sim3text" type="sim3" indexed="true" stored="true"/>
-
-   <!-- make sure custom sims work with dynamic fields -->
-   <dynamicField name="*_sim1" type="sim1" indexed="true" stored="true"/>
-   <dynamicField name="*_sim2" type="sim2" indexed="true" stored="true"/>
-   <dynamicField name="*_sim3" type="sim3" indexed="true" stored="true"/>
- </fields>
-
- <defaultSearchField>sim1text</defaultSearchField>
- <uniqueKey>id</uniqueKey>
-
- <!-- Global similarity, defers to the fieldType.
-      
-      Even though SchemaSimilarityFactory is the current implicit default in IndexSchema, we
-      are explicit about it here in this schema file because TestPerFieldSimilarityClassic overrides
-      the luceneMatchVersion which results in a diff implicit global default - but we still
-      need per-fieldtype sims for that test.
- -->
- <similarity class="solr.SchemaSimilarityFactory"/>
+  <field name="id" type="int" indexed="true" stored="true" multiValued="false" required="false"/>
+  <field name="sim1text" type="sim-explicit" indexed="true" stored="true"/>
+  <field name="sim2text" type="sim-used-as-default-override" indexed="true" stored="true"/>
+  <field name="sim3text" type="sim-none-get-default" indexed="true" stored="true"/>
+  
+  <!-- make sure custom sims work with dynamic fields -->
+  <dynamicField name="*_sim1" type="sim-explicit" indexed="true" stored="true"/>
+  <dynamicField name="*_sim2" type="sim-used-as-default-override" indexed="true" stored="true"/>
+  <dynamicField name="*_sim3" type="sim-none-get-default" indexed="true" stored="true"/>
+
+  <fieldType name="int" class="solr.TrieIntField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>
+  <uniqueKey>id</uniqueKey>
+  
 </schema>

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/BadIndexSchemaTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/BadIndexSchemaTest.java?rev=1715881&r1=1715880&r2=1715881&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/BadIndexSchemaTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/BadIndexSchemaTest.java Mon Nov 23 16:50:49 2015
@@ -119,4 +119,14 @@ public class BadIndexSchemaTest extends
     doTest("bad-schema-bogus-analysis-parameters.xml", "Unknown parameters");
   }
 
+  public void testSimDefaultFieldTypeHasNoExplicitSim() throws Exception {
+    doTest("bad-schema-sim-default-has-no-explicit-sim.xml",
+           "ft-has-no-sim");
+  }
+  
+  public void testSimDefaultFieldTypeDoesNotExist() throws Exception {
+    doTest("bad-schema-sim-default-does-not-exist.xml",
+           "ft-does-not-exist");
+  }
+  
 }

Copied: lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/similarities/TestPerFieldSimilarityWithDefaultOverride.java (from r1715381, lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/similarities/TestPerFieldSimilarity.java)
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/similarities/TestPerFieldSimilarityWithDefaultOverride.java?p2=lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/similarities/TestPerFieldSimilarityWithDefaultOverride.java&p1=lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/similarities/TestPerFieldSimilarity.java&r1=1715381&r2=1715881&rev=1715881&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/similarities/TestPerFieldSimilarity.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/similarities/TestPerFieldSimilarityWithDefaultOverride.java Mon Nov 23 16:50:49 2015
@@ -23,55 +23,54 @@ import org.apache.lucene.search.similari
 import org.junit.BeforeClass;
 
 /**
- * Tests per-field similarity support in the schema
- * @see TestPerFieldSimilarityClassic
+ * Tests per-field similarity support in the schema when SchemaSimilarityFactory is explicitly
+ * configured to use a custom default sim for field types that do not override it.
+ * @see TestPerFieldSimilarity
  */
-public class TestPerFieldSimilarity extends BaseSimilarityTestCase {
+public class TestPerFieldSimilarityWithDefaultOverride extends BaseSimilarityTestCase {
 
   @BeforeClass
   public static void beforeClass() throws Exception {
-    initCore("solrconfig-basic.xml","schema-sim.xml");
+    initCore("solrconfig-basic.xml","schema-sim-default-override.xml");
   }
   
   /** test a field where the sim is specified directly */
   public void testDirect() throws Exception {
-    assertEquals(SweetSpotSimilarity.class, getSimilarity("sim1text").getClass());
+    assertNotNull(getSimilarity("sim1text", SweetSpotSimilarity.class));
   }
   
   /** ... and for a dynamic field */
   public void testDirectDynamic() throws Exception {
-    assertEquals(SweetSpotSimilarity.class, getSimilarity("text_sim1").getClass());
+    assertNotNull(getSimilarity("text_sim1", SweetSpotSimilarity.class));
   }
   
-  /** test a field where a configurable sim factory is defined */
-  public void testFactory() throws Exception {
-    Similarity sim = getSimilarity("sim2text");
-    assertEquals(MockConfigurableSimilarity.class, sim.getClass());
-    assertEquals("is there an echo?", ((MockConfigurableSimilarity)sim).getPassthrough());
+  /** test a field where a configurable sim factory is explicitly defined */
+  public void testDirectFactory() throws Exception {
+    MockConfigurableSimilarity sim = getSimilarity("sim2text", MockConfigurableSimilarity.class);
+    assertEquals("is there an echo?", sim.getPassthrough());
   }
   
   /** ... and for a dynamic field */
-  public void testFactoryDynamic() throws Exception {
-    Similarity sim = getSimilarity("text_sim2");
-    assertEquals(MockConfigurableSimilarity.class, sim.getClass());
-    assertEquals("is there an echo?", ((MockConfigurableSimilarity)sim).getPassthrough());
+  public void testDirectFactoryDynamic() throws Exception {
+    MockConfigurableSimilarity sim = getSimilarity("text_sim2", MockConfigurableSimilarity.class);
+    assertEquals("is there an echo?", sim.getPassthrough());
   }
   
   /** test a field where no similarity is specified */
   public void testDefaults() throws Exception {
-    Similarity sim = getSimilarity("sim3text");
-    assertEquals(BM25Similarity.class, sim.getClass());;
+    MockConfigurableSimilarity sim = getSimilarity("sim3text", MockConfigurableSimilarity.class);
+    assertEquals("is there an echo?", sim.getPassthrough());
   }
   
   /** ... and for a dynamic field */
   public void testDefaultsDynamic() throws Exception {
-    Similarity sim = getSimilarity("text_sim3");
-    assertEquals(BM25Similarity.class, sim.getClass());
+    MockConfigurableSimilarity sim = getSimilarity("text_sim3", MockConfigurableSimilarity.class);
+    assertEquals("is there an echo?", sim.getPassthrough());
   }
   
   /** test a field that does not exist */
   public void testNonexistent() throws Exception {
-    Similarity sim = getSimilarity("sdfdsfdsfdswr5fsdfdsfdsfs");
-    assertEquals(BM25Similarity.class, sim.getClass());
+    MockConfigurableSimilarity sim = getSimilarity("text_sim3", MockConfigurableSimilarity.class);
+    assertEquals("is there an echo?", sim.getPassthrough());
   }
 }