diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index e1eec885532..72572be902f 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -55,6 +55,10 @@ Upgrading from Solr 5.x refrenced in your schema.xml, edit your config to use the functionally identical ClassicSimilarityFactory. See SOLR-8239 for more details. +* SchemaSimilarityFactory has been modified to use BM25Similarity as the default for fieldTypes that + do not explicitly declare a Similarity. The legacy behavior of using ClassicSimilarity as the + default will occur if the luceneMatchVersion for the collection is less then 6.0. See SOLR-8261 for + more details. Detailed Change List ---------------------- @@ -130,6 +134,8 @@ Other Changes * SOLR-8114: in Grouping.java rename groupSort and sort to withinGroupSort and groupSort (Christine Poerschke) +* SOLR-8261: Change SchemaSimilarityFactory default to BM25Similarity (hossman) + ================== 5.4.0 ================== Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release diff --git a/solr/core/src/java/org/apache/solr/search/similarities/SchemaSimilarityFactory.java b/solr/core/src/java/org/apache/solr/search/similarities/SchemaSimilarityFactory.java index 390a964e404..831a358c982 100644 --- a/solr/core/src/java/org/apache/solr/search/similarities/SchemaSimilarityFactory.java +++ b/solr/core/src/java/org/apache/solr/search/similarities/SchemaSimilarityFactory.java @@ -18,8 +18,11 @@ package org.apache.solr.search.similarities; */ import org.apache.lucene.search.similarities.ClassicSimilarity; +import org.apache.lucene.search.similarities.BM25Similarity; import org.apache.lucene.search.similarities.PerFieldSimilarityWrapper; import org.apache.lucene.search.similarities.Similarity; +import org.apache.lucene.util.Version; + import org.apache.solr.common.params.SolrParams; import org.apache.solr.core.SolrCore; import org.apache.solr.schema.FieldType; @@ -27,10 +30,15 @@ import org.apache.solr.schema.SimilarityFactory; import org.apache.solr.util.plugin.SolrCoreAware; /** + *

* SimilarityFactory that returns a {@link PerFieldSimilarityWrapper} * that delegates to the field type, if it's configured, otherwise - * {@link ClassicSimilarity}. - * + * returns a sensible default depending on the {@link Version} matching configured. + *

+ * *

* NOTE: Users should be aware that in addition to supporting * Similarity configurations specified on individual @@ -44,13 +52,16 @@ import org.apache.solr.util.plugin.SolrCoreAware; * @see FieldType#getSimilarity */ public class SchemaSimilarityFactory extends SimilarityFactory implements SolrCoreAware { - private Similarity similarity; - private Similarity defaultSimilarity = new ClassicSimilarity(); + private Similarity similarity; // set by init + private Similarity defaultSimilarity; // set by inform(SolrCore) private volatile SolrCore core; @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 diff --git a/solr/core/src/test/org/apache/solr/search/similarities/TestPerFieldSimilarity.java b/solr/core/src/test/org/apache/solr/search/similarities/TestPerFieldSimilarity.java index ba20638e352..e01aed462da 100644 --- a/solr/core/src/test/org/apache/solr/search/similarities/TestPerFieldSimilarity.java +++ b/solr/core/src/test/org/apache/solr/search/similarities/TestPerFieldSimilarity.java @@ -18,12 +18,13 @@ package org.apache.solr.search.similarities; */ import org.apache.lucene.misc.SweetSpotSimilarity; -import org.apache.lucene.search.similarities.ClassicSimilarity; +import org.apache.lucene.search.similarities.BM25Similarity; import org.apache.lucene.search.similarities.Similarity; import org.junit.BeforeClass; /** * Tests per-field similarity support in the schema + * @see TestPerFieldSimilarityClassic */ public class TestPerFieldSimilarity extends BaseSimilarityTestCase { @@ -59,18 +60,18 @@ public class TestPerFieldSimilarity extends BaseSimilarityTestCase { /** test a field where no similarity is specified */ public void testDefaults() throws Exception { Similarity sim = getSimilarity("sim3text"); - assertEquals(ClassicSimilarity.class, sim.getClass());; + assertEquals(BM25Similarity.class, sim.getClass());; } /** ... and for a dynamic field */ public void testDefaultsDynamic() throws Exception { Similarity sim = getSimilarity("text_sim3"); - assertEquals(ClassicSimilarity.class, sim.getClass()); + assertEquals(BM25Similarity.class, sim.getClass()); } /** test a field that does not exist */ public void testNonexistent() throws Exception { Similarity sim = getSimilarity("sdfdsfdsfdswr5fsdfdsfdsfs"); - assertEquals(ClassicSimilarity.class, sim.getClass()); + assertEquals(BM25Similarity.class, sim.getClass()); } } diff --git a/solr/core/src/test/org/apache/solr/search/similarities/TestPerFieldSimilarityClassic.java b/solr/core/src/test/org/apache/solr/search/similarities/TestPerFieldSimilarityClassic.java new file mode 100644 index 00000000000..07bf7764256 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/search/similarities/TestPerFieldSimilarityClassic.java @@ -0,0 +1,87 @@ +package org.apache.solr.search.similarities; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +import org.apache.lucene.misc.SweetSpotSimilarity; +import org.apache.lucene.search.similarities.ClassicSimilarity; +import org.apache.lucene.search.similarities.Similarity; +import org.apache.lucene.util.Version; +import org.junit.AfterClass; +import org.junit.BeforeClass; + +/** + * Tests per-field similarity support in the schema when luceneMatchVersion indicates + * {@link ClassicSimilarity} should be the default. + * @see TestPerFieldSimilarity + */ +public class TestPerFieldSimilarityClassic extends BaseSimilarityTestCase { + + @BeforeClass + public static void beforeClass() throws Exception { + // any value below 6.0 should have this behavior + System.setProperty("tests.luceneMatchVersion", Version.LUCENE_5_3_1.toString()); + initCore("solrconfig-basic.xml","schema-sim.xml"); + } + + @AfterClass + public static void afterClass() throws Exception { + System.clearProperty("tests.luceneMatchVersion"); + } + + /** test a field where the sim is specified directly */ + public void testDirect() throws Exception { + assertEquals(SweetSpotSimilarity.class, getSimilarity("sim1text").getClass()); + } + + /** ... and for a dynamic field */ + public void testDirectDynamic() throws Exception { + assertEquals(SweetSpotSimilarity.class, getSimilarity("text_sim1").getClass()); + } + + /** 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()); + } + + /** ... 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()); + } + + /** test a field where no similarity is specified */ + public void testDefaults() throws Exception { + Similarity sim = getSimilarity("sim3text"); + assertEquals(ClassicSimilarity.class, sim.getClass());; + } + + /** ... and for a dynamic field */ + public void testDefaultsDynamic() throws Exception { + Similarity sim = getSimilarity("text_sim3"); + assertEquals(ClassicSimilarity.class, sim.getClass()); + } + + /** test a field that does not exist */ + public void testNonexistent() throws Exception { + Similarity sim = getSimilarity("sdfdsfdsfdswr5fsdfdsfdsfs"); + assertEquals(ClassicSimilarity.class, sim.getClass()); + } +}