All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.solr.search.similarities.SchemaSimilarityFactory Maven / Gradle / Ivy

There is a newer version: 9.7.0
Show newest version
/*
 * 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.
 */
package org.apache.solr.search.similarities;

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.search.similarity.LegacyBM25Similarity;
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;
import org.apache.solr.schema.SimilarityFactory;
import org.apache.solr.util.plugin.SolrCoreAware;

/**
 * 

* SimilarityFactory that returns a global {@link PerFieldSimilarityWrapper} * that delegates to the field type, if it's configured. For field types that * do not have a Similarity explicitly configured, the global Similarity * will use per fieldtype defaults -- either based on an explicitly configured * defaultSimFromFieldType a sensible default depending on the {@link Version} * matching configured: *

*
    *
  • luceneMatchVersion < 8.0 = {@link LegacyBM25Similarity}
  • *
  • luceneMatchVersion >= 8.0 = {@link BM25Similarity}
  • *
*

* The defaultSimFromFieldType option accepts the name of any fieldtype, and uses * whatever Similarity is explicitly configured for that fieldType as the default for * all other field types. For example: *

*
 *   <similarity class="solr.SchemaSimilarityFactory" >
 *     <str name="defaultSimFromFieldType">type-using-custom-dfr</str>
 *   </similarity>
 *   ...
 *   <fieldType name="type-using-custom-dfr" class="solr.TextField">
 *     ...
 *     <similarity class="solr.DFRSimilarityFactory">
 *       <str name="basicModel">I(F)</str>
 *       <str name="afterEffect">B</str>
 *       <str name="normalization">H3</str>
 *       <float name="mu">900</float>
 *     </similarity>
 *   </fieldType>
 * 
*

* In the example above, any fieldtypes that do not define their own </similarity/> * will use the Similarity configured for the type-using-custom-dfr. *

* *

* NOTE: Users should be aware that even when this factory uses a single default * Similarity for some or all fields in a Query, the behavior can be inconsistent * with the behavior of explicitly configuring that same Similarity globally, because * of differences in how some multi-field / multi-clause behavior is defined in * PerFieldSimilarityWrapper. *

* * @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 volatile SolrCore core; // set by inform(SolrCore) private volatile Similarity similarity; // lazy instantiated private Version coreVersion = Version.LATEST; @Override public void inform(SolrCore core) { this.core = core; this.coreVersion = this.core.getSolrConfig().luceneMatchVersion; } @Override public void init(SolrParams args) { defaultSimFromFieldType = args.get(INIT_OPT, null); super.init(args); } @Override public Similarity getSimilarity() { 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 = coreVersion.onOrAfter(Version.LUCENE_8_0_0) ? new BM25Similarity() : new LegacyBM25Similarity(); } else { FieldType defSimFT = core.getLatestSchema().getFieldTypeByName(defaultSimFromFieldType); if (null == defSimFT) { throw new SolrException(ErrorCode.SERVER_ERROR, "SchemaSimilarityFactory configured with " + INIT_OPT + "='" + defaultSimFromFieldType + "' but that does not exist"); } defaultSim = defSimFT.getSimilarity(); if (null == defaultSim) { throw new SolrException(ErrorCode.SERVER_ERROR, "SchemaSimilarityFactory configured with " + INIT_OPT + "='" + defaultSimFromFieldType + "' but that does not define a "); } } similarity = new SchemaSimilarity(defaultSim); } return similarity; } private class SchemaSimilarity extends PerFieldSimilarityWrapper { private Similarity defaultSimilarity; public SchemaSimilarity(Similarity defaultSimilarity) { this.defaultSimilarity = defaultSimilarity; } @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 public String toString() { return "SchemaSimilarity. Default: " + ((get("") == null) ? "null" : get("").toString()); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy