Merge pull request #13942 from s1monw/try_trash_index_guice

Simplify similarity module and friends
This commit is contained in:
Simon Willnauer 2015-10-07 20:51:45 +02:00
commit 4d87c5fb38
31 changed files with 252 additions and 461 deletions

View File

@ -34,7 +34,7 @@ import org.elasticsearch.index.Index;
import org.elasticsearch.index.analysis.AnalysisService; import org.elasticsearch.index.analysis.AnalysisService;
import org.elasticsearch.index.analysis.NamedAnalyzer; import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.similarity.SimilarityLookupService; import org.elasticsearch.index.similarity.SimilarityService;
import org.elasticsearch.index.store.IndexStoreModule; import org.elasticsearch.index.store.IndexStoreModule;
import org.elasticsearch.script.ScriptService; import org.elasticsearch.script.ScriptService;
@ -322,11 +322,11 @@ public class MetaDataIndexUpgradeService extends AbstractComponent {
Index index = new Index(indexMetaData.getIndex()); Index index = new Index(indexMetaData.getIndex());
Settings settings = indexMetaData.settings(); Settings settings = indexMetaData.settings();
try { try {
SimilarityLookupService similarityLookupService = new SimilarityLookupService(index, settings); SimilarityService similarityService = new SimilarityService(index, settings);
// We cannot instantiate real analysis server at this point because the node might not have // We cannot instantiate real analysis server at this point because the node might not have
// been started yet. However, we don't really need real analyzers at this stage - so we can fake it // been started yet. However, we don't really need real analyzers at this stage - so we can fake it
try (AnalysisService analysisService = new FakeAnalysisService(index, settings)) { try (AnalysisService analysisService = new FakeAnalysisService(index, settings)) {
try (MapperService mapperService = new MapperService(index, settings, analysisService, similarityLookupService, scriptService)) { try (MapperService mapperService = new MapperService(index, settings, analysisService, similarityService, scriptService)) {
for (ObjectCursor<MappingMetaData> cursor : indexMetaData.getMappings().values()) { for (ObjectCursor<MappingMetaData> cursor : indexMetaData.getMappings().values()) {
MappingMetaData mappingMetaData = cursor.value; MappingMetaData mappingMetaData = cursor.value;
mapperService.merge(mappingMetaData.type(), mappingMetaData.source(), false, false); mapperService.merge(mappingMetaData.type(), mappingMetaData.source(), false, false);

View File

@ -1,40 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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.elasticsearch.index;
import org.elasticsearch.common.inject.BindingAnnotation;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
*
*/
@BindingAnnotation
@Target({FIELD, PARAMETER})
@Retention(RUNTIME)
@Documented
public @interface LocalNodeId {
}

View File

@ -1,39 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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.elasticsearch.index;
import org.elasticsearch.common.inject.AbstractModule;
/**
*
*/
public class LocalNodeIdModule extends AbstractModule {
private final String localNodeId;
public LocalNodeIdModule(String localNodeId) {
this.localNodeId = localNodeId;
}
@Override
protected void configure() {
bind(String.class).annotatedWith(LocalNodeId.class).toInstance(localNodeId);
}
}

View File

@ -43,7 +43,7 @@ import org.elasticsearch.index.mapper.ip.IpFieldMapper;
import org.elasticsearch.index.mapper.object.ObjectMapper; import org.elasticsearch.index.mapper.object.ObjectMapper;
import org.elasticsearch.index.mapper.object.RootObjectMapper; import org.elasticsearch.index.mapper.object.RootObjectMapper;
import org.elasticsearch.index.settings.IndexSettings; import org.elasticsearch.index.settings.IndexSettings;
import org.elasticsearch.index.similarity.SimilarityLookupService; import org.elasticsearch.index.similarity.SimilarityService;
import org.elasticsearch.script.Script; import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptService; import org.elasticsearch.script.ScriptService;
@ -57,7 +57,7 @@ public class DocumentMapperParser {
final MapperService mapperService; final MapperService mapperService;
final AnalysisService analysisService; final AnalysisService analysisService;
private static final ESLogger logger = Loggers.getLogger(DocumentMapperParser.class); private static final ESLogger logger = Loggers.getLogger(DocumentMapperParser.class);
private final SimilarityLookupService similarityLookupService; private final SimilarityService similarityService;
private final ScriptService scriptService; private final ScriptService scriptService;
private final RootObjectMapper.TypeParser rootObjectTypeParser = new RootObjectMapper.TypeParser(); private final RootObjectMapper.TypeParser rootObjectTypeParser = new RootObjectMapper.TypeParser();
@ -71,12 +71,12 @@ public class DocumentMapperParser {
private volatile SortedMap<String, Mapper.TypeParser> additionalRootMappers; private volatile SortedMap<String, Mapper.TypeParser> additionalRootMappers;
public DocumentMapperParser(@IndexSettings Settings indexSettings, MapperService mapperService, AnalysisService analysisService, public DocumentMapperParser(@IndexSettings Settings indexSettings, MapperService mapperService, AnalysisService analysisService,
SimilarityLookupService similarityLookupService, ScriptService scriptService) { SimilarityService similarityService, ScriptService scriptService) {
this.indexSettings = indexSettings; this.indexSettings = indexSettings;
this.parseFieldMatcher = new ParseFieldMatcher(indexSettings); this.parseFieldMatcher = new ParseFieldMatcher(indexSettings);
this.mapperService = mapperService; this.mapperService = mapperService;
this.analysisService = analysisService; this.analysisService = analysisService;
this.similarityLookupService = similarityLookupService; this.similarityService = similarityService;
this.scriptService = scriptService; this.scriptService = scriptService;
MapBuilder<String, Mapper.TypeParser> typeParsersBuilder = new MapBuilder<String, Mapper.TypeParser>() MapBuilder<String, Mapper.TypeParser> typeParsersBuilder = new MapBuilder<String, Mapper.TypeParser>()
.put(ByteFieldMapper.CONTENT_TYPE, new ByteFieldMapper.TypeParser()) .put(ByteFieldMapper.CONTENT_TYPE, new ByteFieldMapper.TypeParser())
@ -142,7 +142,7 @@ public class DocumentMapperParser {
} }
public Mapper.TypeParser.ParserContext parserContext(String type) { public Mapper.TypeParser.ParserContext parserContext(String type) {
return new Mapper.TypeParser.ParserContext(type, analysisService, similarityLookupService, mapperService, typeParsers, indexVersionCreated, parseFieldMatcher); return new Mapper.TypeParser.ParserContext(type, analysisService, similarityService::getSimilarity, mapperService, typeParsers::get, indexVersionCreated, parseFieldMatcher);
} }
public DocumentMapper parse(String source) throws MapperParsingException { public DocumentMapper parse(String source) throws MapperParsingException {

View File

@ -34,8 +34,8 @@ import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.fielddata.FieldDataType; import org.elasticsearch.index.fielddata.FieldDataType;
import org.elasticsearch.index.mapper.core.TypeParsers; import org.elasticsearch.index.mapper.core.TypeParsers;
import org.elasticsearch.index.mapper.internal.AllFieldMapper; import org.elasticsearch.index.mapper.internal.AllFieldMapper;
import org.elasticsearch.index.similarity.SimilarityLookupService;
import org.elasticsearch.index.similarity.SimilarityProvider; import org.elasticsearch.index.similarity.SimilarityProvider;
import org.elasticsearch.index.similarity.SimilarityService;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
@ -447,7 +447,7 @@ public abstract class FieldMapper extends Mapper {
if (fieldType().similarity() != null) { if (fieldType().similarity() != null) {
builder.field("similarity", fieldType().similarity().name()); builder.field("similarity", fieldType().similarity().name());
} else if (includeDefaults) { } else if (includeDefaults) {
builder.field("similarity", SimilarityLookupService.DEFAULT_SIMILARITY); builder.field("similarity", SimilarityService.DEFAULT_SIMILARITY);
} }
if (includeDefaults || hasCustomFieldDataSettings()) { if (includeDefaults || hasCustomFieldDataSettings()) {

View File

@ -19,7 +19,6 @@
package org.elasticsearch.index.mapper; package org.elasticsearch.index.mapper;
import com.google.common.collect.ImmutableMap;
import org.elasticsearch.Version; import org.elasticsearch.Version;
import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.ParseFieldMatcher;
@ -27,9 +26,10 @@ import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.index.analysis.AnalysisService; import org.elasticsearch.index.analysis.AnalysisService;
import org.elasticsearch.index.similarity.SimilarityLookupService; import org.elasticsearch.index.similarity.SimilarityProvider;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
public abstract class Mapper implements ToXContent, Iterable<Mapper> { public abstract class Mapper implements ToXContent, Iterable<Mapper> {
@ -85,18 +85,18 @@ public abstract class Mapper implements ToXContent, Iterable<Mapper> {
private final AnalysisService analysisService; private final AnalysisService analysisService;
private final SimilarityLookupService similarityLookupService; private final Function<String, SimilarityProvider> similarityLookupService;
private final MapperService mapperService; private final MapperService mapperService;
private final ImmutableMap<String, TypeParser> typeParsers; private final Function<String, TypeParser> typeParsers;
private final Version indexVersionCreated; private final Version indexVersionCreated;
private final ParseFieldMatcher parseFieldMatcher; private final ParseFieldMatcher parseFieldMatcher;
public ParserContext(String type, AnalysisService analysisService, SimilarityLookupService similarityLookupService, public ParserContext(String type, AnalysisService analysisService, Function<String, SimilarityProvider> similarityLookupService,
MapperService mapperService, ImmutableMap<String, TypeParser> typeParsers, MapperService mapperService, Function<String, TypeParser> typeParsers,
Version indexVersionCreated, ParseFieldMatcher parseFieldMatcher) { Version indexVersionCreated, ParseFieldMatcher parseFieldMatcher) {
this.type = type; this.type = type;
this.analysisService = analysisService; this.analysisService = analysisService;
@ -115,8 +115,8 @@ public abstract class Mapper implements ToXContent, Iterable<Mapper> {
return analysisService; return analysisService;
} }
public SimilarityLookupService similarityLookupService() { public SimilarityProvider getSimilarity(String name) {
return similarityLookupService; return similarityLookupService.apply(name);
} }
public MapperService mapperService() { public MapperService mapperService() {
@ -124,7 +124,7 @@ public abstract class Mapper implements ToXContent, Iterable<Mapper> {
} }
public TypeParser typeParser(String type) { public TypeParser typeParser(String type) {
return typeParsers.get(Strings.toUnderscoreCase(type)); return typeParsers.apply(Strings.toUnderscoreCase(type));
} }
public Version indexVersionCreated() { public Version indexVersionCreated() {

View File

@ -52,7 +52,7 @@ import org.elasticsearch.index.mapper.Mapper.BuilderContext;
import org.elasticsearch.index.mapper.internal.TypeFieldMapper; import org.elasticsearch.index.mapper.internal.TypeFieldMapper;
import org.elasticsearch.index.mapper.object.ObjectMapper; import org.elasticsearch.index.mapper.object.ObjectMapper;
import org.elasticsearch.index.settings.IndexSettings; import org.elasticsearch.index.settings.IndexSettings;
import org.elasticsearch.index.similarity.SimilarityLookupService; import org.elasticsearch.index.similarity.SimilarityService;
import org.elasticsearch.indices.InvalidTypeNameException; import org.elasticsearch.indices.InvalidTypeNameException;
import org.elasticsearch.indices.TypeMissingException; import org.elasticsearch.indices.TypeMissingException;
import org.elasticsearch.percolator.PercolatorService; import org.elasticsearch.percolator.PercolatorService;
@ -125,12 +125,12 @@ public class MapperService extends AbstractIndexComponent implements Closeable {
@Inject @Inject
public MapperService(Index index, @IndexSettings Settings indexSettings, AnalysisService analysisService, public MapperService(Index index, @IndexSettings Settings indexSettings, AnalysisService analysisService,
SimilarityLookupService similarityLookupService, SimilarityService similarityService,
ScriptService scriptService) { ScriptService scriptService) {
super(index, indexSettings); super(index, indexSettings);
this.analysisService = analysisService; this.analysisService = analysisService;
this.fieldTypes = new FieldTypeLookup(); this.fieldTypes = new FieldTypeLookup();
this.documentParser = new DocumentMapperParser(indexSettings, this, analysisService, similarityLookupService, scriptService); this.documentParser = new DocumentMapperParser(indexSettings, this, analysisService, similarityService, scriptService);
this.indexAnalyzer = new MapperAnalyzerWrapper(analysisService.defaultIndexAnalyzer(), p -> p.indexAnalyzer()); this.indexAnalyzer = new MapperAnalyzerWrapper(analysisService.defaultIndexAnalyzer(), p -> p.indexAnalyzer());
this.searchAnalyzer = new MapperAnalyzerWrapper(analysisService.defaultSearchAnalyzer(), p -> p.searchAnalyzer()); this.searchAnalyzer = new MapperAnalyzerWrapper(analysisService.defaultSearchAnalyzer(), p -> p.searchAnalyzer());
this.searchQuoteAnalyzer = new MapperAnalyzerWrapper(analysisService.defaultSearchQuoteAnalyzer(), p -> p.searchQuoteAnalyzer()); this.searchQuoteAnalyzer = new MapperAnalyzerWrapper(analysisService.defaultSearchQuoteAnalyzer(), p -> p.searchQuoteAnalyzer());

View File

@ -173,7 +173,7 @@ public class TypeParsers {
builder.omitNorms(nodeBooleanValue(propNode)); builder.omitNorms(nodeBooleanValue(propNode));
iterator.remove(); iterator.remove();
} else if (propName.equals("similarity")) { } else if (propName.equals("similarity")) {
builder.similarity(parserContext.similarityLookupService().similarity(propNode.toString())); builder.similarity(parserContext.getSimilarity(propNode.toString()));
iterator.remove(); iterator.remove();
} else if (parseMultiField(builder, name, parserContext, propName, propNode)) { } else if (parseMultiField(builder, name, parserContext, propName, propNode)) {
iterator.remove(); iterator.remove();
@ -277,7 +277,7 @@ public class TypeParsers {
// ignore for old indexes // ignore for old indexes
iterator.remove(); iterator.remove();
} else if (propName.equals("similarity")) { } else if (propName.equals("similarity")) {
builder.similarity(parserContext.similarityLookupService().similarity(propNode.toString())); builder.similarity(parserContext.getSimilarity(propNode.toString()));
iterator.remove(); iterator.remove();
} else if (propName.equals("fielddata")) { } else if (propName.equals("fielddata")) {
final Settings settings = Settings.builder().put(SettingsLoader.Helper.loadNestedFromMap(nodeMapValue(propNode, "fielddata"))).build(); final Settings settings = Settings.builder().put(SettingsLoader.Helper.loadNestedFromMap(nodeMapValue(propNode, "fielddata"))).build();

View File

@ -41,7 +41,7 @@ import org.elasticsearch.index.mapper.MergeResult;
import org.elasticsearch.index.mapper.MetadataFieldMapper; import org.elasticsearch.index.mapper.MetadataFieldMapper;
import org.elasticsearch.index.mapper.ParseContext; import org.elasticsearch.index.mapper.ParseContext;
import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.index.similarity.SimilarityLookupService; import org.elasticsearch.index.similarity.SimilarityService;
import java.io.IOException; import java.io.IOException;
import java.util.Iterator; import java.util.Iterator;
@ -300,7 +300,7 @@ public class AllFieldMapper extends MetadataFieldMapper {
if (fieldType().similarity() != null) { if (fieldType().similarity() != null) {
builder.field("similarity", fieldType().similarity().name()); builder.field("similarity", fieldType().similarity().name());
} else if (includeDefaults) { } else if (includeDefaults) {
builder.field("similarity", SimilarityLookupService.DEFAULT_SIMILARITY); builder.field("similarity", SimilarityService.DEFAULT_SIMILARITY);
} }
} }

View File

@ -148,7 +148,7 @@ public class QueryShardContext {
} }
public Similarity searchSimilarity() { public Similarity searchSimilarity() {
return indexQueryParser.similarityService != null ? indexQueryParser.similarityService.similarity() : null; return indexQueryParser.similarityService != null ? indexQueryParser.similarityService.similarity(indexQueryParser.mapperService) : null;
} }
public String defaultField() { public String defaultField() {

View File

@ -1394,7 +1394,7 @@ public class IndexShard extends AbstractIndexShardComponent implements IndexSett
}; };
return new EngineConfig(shardId, return new EngineConfig(shardId,
threadPool, indexingService, indexSettings, warmer, store, deletionPolicy, mergePolicyConfig.getMergePolicy(), mergeSchedulerConfig, threadPool, indexingService, indexSettings, warmer, store, deletionPolicy, mergePolicyConfig.getMergePolicy(), mergeSchedulerConfig,
mapperService.indexAnalyzer(), similarityService.similarity(), codecService, failedEngineListener, translogRecoveryPerformer, indexCache.query(), cachingPolicy, translogConfig); mapperService.indexAnalyzer(), similarityService.similarity(mapperService), codecService, failedEngineListener, translogRecoveryPerformer, indexCache.query(), cachingPolicy, translogConfig);
} }
private static class IndexShardOperationCounter extends AbstractRefCounted { private static class IndexShardOperationCounter extends AbstractRefCounted {

View File

@ -21,8 +21,6 @@ package org.elasticsearch.index.similarity;
import org.apache.lucene.search.similarities.BM25Similarity; import org.apache.lucene.search.similarities.BM25Similarity;
import org.apache.lucene.search.similarities.Similarity; import org.apache.lucene.search.similarities.Similarity;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.inject.assistedinject.Assisted;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
/** /**
@ -40,8 +38,7 @@ public class BM25SimilarityProvider extends AbstractSimilarityProvider {
private final BM25Similarity similarity; private final BM25Similarity similarity;
@Inject public BM25SimilarityProvider(String name, Settings settings) {
public BM25SimilarityProvider(@Assisted String name, @Assisted Settings settings) {
super(name); super(name);
float k1 = settings.getAsFloat("k1", 1.2f); float k1 = settings.getAsFloat("k1", 1.2f);
float b = settings.getAsFloat("b", 0.75f); float b = settings.getAsFloat("b", 0.75f);

View File

@ -62,8 +62,7 @@ public class DFRSimilarityProvider extends AbstractSimilarityProvider {
private final DFRSimilarity similarity; private final DFRSimilarity similarity;
@Inject public DFRSimilarityProvider(String name, Settings settings) {
public DFRSimilarityProvider(@Assisted String name, @Assisted Settings settings) {
super(name); super(name);
BasicModel basicModel = parseBasicModel(settings); BasicModel basicModel = parseBasicModel(settings);
AfterEffect afterEffect = parseAfterEffect(settings); AfterEffect afterEffect = parseAfterEffect(settings);

View File

@ -20,8 +20,6 @@
package org.elasticsearch.index.similarity; package org.elasticsearch.index.similarity;
import org.apache.lucene.search.similarities.DefaultSimilarity; import org.apache.lucene.search.similarities.DefaultSimilarity;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.inject.assistedinject.Assisted;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
/** /**
@ -37,8 +35,7 @@ public class DefaultSimilarityProvider extends AbstractSimilarityProvider {
private final DefaultSimilarity similarity = new DefaultSimilarity(); private final DefaultSimilarity similarity = new DefaultSimilarity();
@Inject public DefaultSimilarityProvider(String name, Settings settings) {
public DefaultSimilarityProvider(@Assisted String name, @Assisted Settings settings) {
super(name); super(name);
boolean discountOverlaps = settings.getAsBoolean("discount_overlaps", true); boolean discountOverlaps = settings.getAsBoolean("discount_overlaps", true);
this.similarity.setDiscountOverlaps(discountOverlaps); this.similarity.setDiscountOverlaps(discountOverlaps);

View File

@ -22,8 +22,6 @@ package org.elasticsearch.index.similarity;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import org.apache.lucene.search.similarities.*; import org.apache.lucene.search.similarities.*;
import org.elasticsearch.common.collect.MapBuilder; import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.inject.assistedinject.Assisted;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
/** /**
@ -56,8 +54,7 @@ public class IBSimilarityProvider extends AbstractSimilarityProvider {
private final IBSimilarity similarity; private final IBSimilarity similarity;
@Inject public IBSimilarityProvider(String name, Settings settings) {
public IBSimilarityProvider(@Assisted String name, @Assisted Settings settings) {
super(name); super(name);
Distribution distribution = parseDistribution(settings); Distribution distribution = parseDistribution(settings);
Lambda lambda = parseLambda(settings); Lambda lambda = parseLambda(settings);

View File

@ -21,8 +21,6 @@ package org.elasticsearch.index.similarity;
import org.apache.lucene.search.similarities.LMDirichletSimilarity; import org.apache.lucene.search.similarities.LMDirichletSimilarity;
import org.apache.lucene.search.similarities.Similarity; import org.apache.lucene.search.similarities.Similarity;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.inject.assistedinject.Assisted;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
/** /**
@ -38,8 +36,7 @@ public class LMDirichletSimilarityProvider extends AbstractSimilarityProvider {
private final LMDirichletSimilarity similarity; private final LMDirichletSimilarity similarity;
@Inject public LMDirichletSimilarityProvider(String name, Settings settings) {
public LMDirichletSimilarityProvider(@Assisted String name, @Assisted Settings settings) {
super(name); super(name);
float mu = settings.getAsFloat("mu", 2000f); float mu = settings.getAsFloat("mu", 2000f);
this.similarity = new LMDirichletSimilarity(mu); this.similarity = new LMDirichletSimilarity(mu);

View File

@ -38,8 +38,7 @@ public class LMJelinekMercerSimilarityProvider extends AbstractSimilarityProvide
private final LMJelinekMercerSimilarity similarity; private final LMJelinekMercerSimilarity similarity;
@Inject public LMJelinekMercerSimilarityProvider(String name, Settings settings) {
public LMJelinekMercerSimilarityProvider(@Assisted String name, @Assisted Settings settings) {
super(name); super(name);
float lambda = settings.getAsFloat("lambda", 0.1f); float lambda = settings.getAsFloat("lambda", 0.1f);
this.similarity = new LMJelinekMercerSimilarity(lambda); this.similarity = new LMJelinekMercerSimilarity(lambda);

View File

@ -1,73 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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.elasticsearch.index.similarity;
import org.apache.lucene.search.similarities.Similarity;
import org.elasticsearch.common.settings.Settings;
/**
* {@link SimilarityProvider} for pre-built Similarities
*/
public class PreBuiltSimilarityProvider extends AbstractSimilarityProvider {
public static class Factory implements SimilarityProvider.Factory {
private final PreBuiltSimilarityProvider similarity;
public Factory(String name, Similarity similarity) {
this.similarity = new PreBuiltSimilarityProvider(name, similarity);
}
@Override
public SimilarityProvider create(String name, Settings settings) {
return similarity;
}
public String name() {
return similarity.name();
}
public SimilarityProvider get() {
return similarity;
}
}
private final Similarity similarity;
/**
* Creates a new {@link PreBuiltSimilarityProvider} with the given name and given
* pre-built Similarity
*
* @param name Name of the Provider
* @param similarity Pre-built Similarity
*/
public PreBuiltSimilarityProvider(String name, Similarity similarity) {
super(name);
this.similarity = similarity;
}
/**
* {@inheritDoc}
*/
@Override
public Similarity get() {
return similarity;
}
}

View File

@ -1,56 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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.elasticsearch.index.similarity;
import com.google.common.collect.ImmutableMap;
import org.apache.lucene.search.similarities.BM25Similarity;
import org.apache.lucene.search.similarities.DefaultSimilarity;
import org.elasticsearch.common.collect.MapBuilder;
import java.util.Collection;
/**
* Cache of pre-defined Similarities
*/
public class Similarities {
private static final ImmutableMap<String, PreBuiltSimilarityProvider.Factory> PRE_BUILT_SIMILARITIES;
static {
MapBuilder<String, PreBuiltSimilarityProvider.Factory> similarities = MapBuilder.newMapBuilder();
similarities.put(SimilarityLookupService.DEFAULT_SIMILARITY,
new PreBuiltSimilarityProvider.Factory(SimilarityLookupService.DEFAULT_SIMILARITY, new DefaultSimilarity()));
similarities.put("BM25", new PreBuiltSimilarityProvider.Factory("BM25", new BM25Similarity()));
PRE_BUILT_SIMILARITIES = similarities.immutableMap();
}
private Similarities() {
}
/**
* Returns the list of pre-defined SimilarityProvider Factories
*
* @return Pre-defined SimilarityProvider Factories
*/
public static Collection<PreBuiltSimilarityProvider.Factory> listFactories() {
return PRE_BUILT_SIMILARITIES.values();
}
}

View File

@ -1,85 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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.elasticsearch.index.similarity;
import com.google.common.collect.ImmutableMap;
import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.AbstractIndexComponent;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.settings.IndexSettings;
import java.util.Map;
/**
* Service for looking up configured {@link SimilarityProvider} implementations by name.
* <p>
* The service instantiates the Providers through their Factories using configuration
* values found with the {@link SimilarityModule#SIMILARITY_SETTINGS_PREFIX} prefix.
*/
public class SimilarityLookupService extends AbstractIndexComponent {
public final static String DEFAULT_SIMILARITY = "default";
private final ImmutableMap<String, SimilarityProvider> similarities;
public SimilarityLookupService(Index index, Settings indexSettings) {
this(index, indexSettings, ImmutableMap.<String, SimilarityProvider.Factory>of());
}
@Inject
public SimilarityLookupService(Index index, @IndexSettings Settings indexSettings, Map<String, SimilarityProvider.Factory> similarities) {
super(index, indexSettings);
MapBuilder<String, SimilarityProvider> providers = MapBuilder.newMapBuilder();
Map<String, Settings> similaritySettings = indexSettings.getGroups(SimilarityModule.SIMILARITY_SETTINGS_PREFIX);
for (Map.Entry<String, SimilarityProvider.Factory> entry : similarities.entrySet()) {
String name = entry.getKey();
SimilarityProvider.Factory factory = entry.getValue();
Settings settings = similaritySettings.get(name);
if (settings == null) {
settings = Settings.Builder.EMPTY_SETTINGS;
}
providers.put(name, factory.create(name, settings));
}
// For testing
for (PreBuiltSimilarityProvider.Factory factory : Similarities.listFactories()) {
if (!providers.containsKey(factory.name())) {
providers.put(factory.name(), factory.get());
}
}
this.similarities = providers.immutableMap();
}
/**
* Returns the {@link SimilarityProvider} with the given name
*
* @param name Name of the SimilarityProvider to find
* @return {@link SimilarityProvider} with the given name, or {@code null} if no Provider exists
*/
public SimilarityProvider similarity(String name) {
return similarities.get(name);
}
}

View File

@ -20,19 +20,18 @@
package org.elasticsearch.index.similarity; package org.elasticsearch.index.similarity;
import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.inject.Scopes;
import org.elasticsearch.common.inject.assistedinject.FactoryProvider;
import org.elasticsearch.common.inject.multibindings.MapBinder;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.Index;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.function.BiFunction;
/** /**
* {@link SimilarityModule} is responsible gathering registered and configured {@link SimilarityProvider} * {@link SimilarityModule} is responsible gathering registered and configured {@link SimilarityProvider}
* implementations and making them available through the {@link SimilarityLookupService} and {@link SimilarityService}. * implementations and making them available through the {@link SimilarityService}.
* *
* New {@link SimilarityProvider} implementations can be registered through {@link #addSimilarity(String, Class)} * New {@link SimilarityProvider} implementations can be registered through {@link #addSimilarity(String, BiFunction)}
* while existing Providers can be referenced through Settings under the {@link #SIMILARITY_SETTINGS_PREFIX} prefix * while existing Providers can be referenced through Settings under the {@link #SIMILARITY_SETTINGS_PREFIX} prefix
* along with the "type" value. For example, to reference the {@link BM25SimilarityProvider}, the configuration * along with the "type" value. For example, to reference the {@link BM25SimilarityProvider}, the configuration
* <tt>"index.similarity.my_similarity.type : "BM25"</tt> can be used. * <tt>"index.similarity.my_similarity.type : "BM25"</tt> can be used.
@ -42,16 +41,12 @@ public class SimilarityModule extends AbstractModule {
public static final String SIMILARITY_SETTINGS_PREFIX = "index.similarity"; public static final String SIMILARITY_SETTINGS_PREFIX = "index.similarity";
private final Settings settings; private final Settings settings;
private final Map<String, Class<? extends SimilarityProvider>> similarities = new HashMap<>(); private final Map<String, BiFunction<String, Settings, SimilarityProvider>> similarities = new HashMap<>();
private final Index index;
public SimilarityModule(Settings settings) { public SimilarityModule(Index index, Settings settings) {
this.settings = settings; this.settings = settings;
addSimilarity("default", DefaultSimilarityProvider.class); this.index = index;
addSimilarity("BM25", BM25SimilarityProvider.class);
addSimilarity("DFR", DFRSimilarityProvider.class);
addSimilarity("IB", IBSimilarityProvider.class);
addSimilarity("LMDirichlet", LMDirichletSimilarityProvider.class);
addSimilarity("LMJelinekMercer", LMJelinekMercerSimilarityProvider.class);
} }
/** /**
@ -60,36 +55,16 @@ public class SimilarityModule extends AbstractModule {
* @param name Name of the SimilarityProvider * @param name Name of the SimilarityProvider
* @param similarity SimilarityProvider to register * @param similarity SimilarityProvider to register
*/ */
public void addSimilarity(String name, Class<? extends SimilarityProvider> similarity) { public void addSimilarity(String name, BiFunction<String, Settings, SimilarityProvider> similarity) {
if (similarities.containsKey(name) || SimilarityService.BUILT_IN.containsKey(name)) {
throw new IllegalArgumentException("similarity for name: [" + name + " is already registered");
}
similarities.put(name, similarity); similarities.put(name, similarity);
} }
@Override @Override
protected void configure() { protected void configure() {
MapBinder<String, SimilarityProvider.Factory> similarityBinder = SimilarityService service = new SimilarityService(index, settings, new HashMap<>(similarities));
MapBinder.newMapBinder(binder(), String.class, SimilarityProvider.Factory.class); bind(SimilarityService.class).toInstance(service);
Map<String, Settings> similaritySettings = settings.getGroups(SIMILARITY_SETTINGS_PREFIX);
for (Map.Entry<String, Settings> entry : similaritySettings.entrySet()) {
String name = entry.getKey();
Settings settings = entry.getValue();
String typeName = settings.get("type");
if (typeName == null) {
throw new IllegalArgumentException("Similarity [" + name + "] must have an associated type");
} else if (similarities.containsKey(typeName) == false) {
throw new IllegalArgumentException("Unknown Similarity type [" + typeName + "] for [" + name + "]");
}
similarityBinder.addBinding(entry.getKey()).toProvider(FactoryProvider.newFactory(SimilarityProvider.Factory.class, similarities.get(typeName))).in(Scopes.SINGLETON);
}
for (PreBuiltSimilarityProvider.Factory factory : Similarities.listFactories()) {
if (!similarities.containsKey(factory.name())) {
similarityBinder.addBinding(factory.name()).toInstance(factory);
}
}
bind(SimilarityLookupService.class).asEagerSingleton();
bind(SimilarityService.class).asEagerSingleton();
} }
} }

View File

@ -40,19 +40,4 @@ public interface SimilarityProvider {
* @return Provided {@link Similarity} * @return Provided {@link Similarity}
*/ */
Similarity get(); Similarity get();
/**
* Factory for creating {@link SimilarityProvider} instances
*/
public static interface Factory {
/**
* Creates a new {@link SimilarityProvider} instance
*
* @param name Name of the provider
* @param settings Settings to be used by the Provider
* @return {@link SimilarityProvider} instance created by the Factory
*/
SimilarityProvider create(String name, Settings settings);
}
} }

View File

@ -25,55 +25,96 @@ import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.AbstractIndexComponent; import org.elasticsearch.index.AbstractIndexComponent;
import org.elasticsearch.index.Index; import org.elasticsearch.index.Index;
import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.settings.IndexSettings; import org.elasticsearch.index.settings.IndexSettings;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiFunction;
/** /**
* *
*/ */
public class SimilarityService extends AbstractIndexComponent { public class SimilarityService extends AbstractIndexComponent {
private final SimilarityLookupService similarityLookupService; public final static String DEFAULT_SIMILARITY = "default";
private final MapperService mapperService; private final Similarity defaultSimilarity;
private final Similarity baseSimilarity;
private final Similarity perFieldSimilarity; private final Map<String, SimilarityProvider> similarities;
static final Map<String, BiFunction<String, Settings, SimilarityProvider>> DEFAULTS;
static final Map<String, BiFunction<String, Settings, SimilarityProvider>> BUILT_IN;
static {
Map<String, BiFunction<String, Settings, SimilarityProvider>> defaults = new HashMap<>();
Map<String, BiFunction<String, Settings, SimilarityProvider>> buildIn = new HashMap<>();
defaults.put("default", DefaultSimilarityProvider::new);
defaults.put("BM25", BM25SimilarityProvider::new);
buildIn.put("default", DefaultSimilarityProvider::new);
buildIn.put("BM25", BM25SimilarityProvider::new);
buildIn.put("DFR", DFRSimilarityProvider::new);
buildIn.put("IB", IBSimilarityProvider::new);
buildIn.put("LMDirichlet", LMDirichletSimilarityProvider::new);
buildIn.put("LMJelinekMercer", LMJelinekMercerSimilarityProvider::new);
DEFAULTS = Collections.unmodifiableMap(defaults);
BUILT_IN = Collections.unmodifiableMap(buildIn);
}
public SimilarityService(Index index) { public SimilarityService(Index index) {
this(index, Settings.Builder.EMPTY_SETTINGS); this(index, Settings.Builder.EMPTY_SETTINGS);
} }
public SimilarityService(Index index, Settings settings) { public SimilarityService(Index index, Settings settings) {
this(index, settings, new SimilarityLookupService(index, settings), null); this(index, settings, Collections.EMPTY_MAP);
} }
@Inject @Inject
public SimilarityService(Index index, @IndexSettings Settings indexSettings, public SimilarityService(Index index, @IndexSettings Settings indexSettings, Map<String, BiFunction<String, Settings, SimilarityProvider>> similarities) {
final SimilarityLookupService similarityLookupService, final MapperService mapperService) {
super(index, indexSettings); super(index, indexSettings);
this.similarityLookupService = similarityLookupService; Map<String, SimilarityProvider> providers = new HashMap<>(similarities.size());
this.mapperService = mapperService; Map<String, Settings> similaritySettings = indexSettings.getGroups(SimilarityModule.SIMILARITY_SETTINGS_PREFIX);
for (Map.Entry<String, Settings> entry : similaritySettings.entrySet()) {
Similarity defaultSimilarity = similarityLookupService.similarity(SimilarityLookupService.DEFAULT_SIMILARITY).get(); String name = entry.getKey();
Settings settings = entry.getValue();
String typeName = settings.get("type");
if (typeName == null) {
throw new IllegalArgumentException("Similarity [" + name + "] must have an associated type");
} else if ((similarities.containsKey(typeName) || BUILT_IN.containsKey(typeName)) == false) {
throw new IllegalArgumentException("Unknown Similarity type [" + typeName + "] for [" + name + "]");
}
BiFunction<String, Settings, SimilarityProvider> factory = similarities.getOrDefault(typeName, BUILT_IN.get(typeName));
if (settings == null) {
settings = Settings.Builder.EMPTY_SETTINGS;
}
providers.put(name, factory.apply(name, settings));
}
addSimilarities(similaritySettings, providers, DEFAULTS);
this.similarities = providers;
defaultSimilarity = providers.get(SimilarityService.DEFAULT_SIMILARITY).get();
// Expert users can configure the base type as being different to default, but out-of-box we use default. // Expert users can configure the base type as being different to default, but out-of-box we use default.
Similarity baseSimilarity = (similarityLookupService.similarity("base") != null) ? similarityLookupService.similarity("base").get() : baseSimilarity = (providers.get("base") != null) ? providers.get("base").get() :
defaultSimilarity;
this.perFieldSimilarity = (mapperService != null) ? new PerFieldSimilarity(defaultSimilarity, baseSimilarity, mapperService) :
defaultSimilarity; defaultSimilarity;
} }
public Similarity similarity() { public Similarity similarity(MapperService mapperService) {
return perFieldSimilarity; // TODO we can maybe factor out MapperService here entirely by introducing an interface for the lookup?
return (mapperService != null) ? new PerFieldSimilarity(defaultSimilarity, baseSimilarity, mapperService) :
defaultSimilarity;
} }
public SimilarityLookupService similarityLookupService() { private void addSimilarities(Map<String, Settings> similaritySettings, Map<String, SimilarityProvider> providers, Map<String, BiFunction<String, Settings, SimilarityProvider>> similarities) {
return similarityLookupService; for (Map.Entry<String, BiFunction<String, Settings, SimilarityProvider>> entry : similarities.entrySet()) {
String name = entry.getKey();
BiFunction<String, Settings, SimilarityProvider> factory = entry.getValue();
Settings settings = similaritySettings.get(name);
if (settings == null) {
settings = Settings.Builder.EMPTY_SETTINGS;
}
providers.put(name, factory.apply(name, settings));
}
} }
public MapperService mapperService() { public SimilarityProvider getSimilarity(String name) {
return mapperService; return similarities.get(name);
} }
static class PerFieldSimilarity extends PerFieldSimilarityWrapper { static class PerFieldSimilarity extends PerFieldSimilarityWrapper {

View File

@ -52,7 +52,6 @@ import org.elasticsearch.index.IndexModule;
import org.elasticsearch.index.IndexNameModule; import org.elasticsearch.index.IndexNameModule;
import org.elasticsearch.index.IndexNotFoundException; import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.index.IndexService; import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.LocalNodeIdModule;
import org.elasticsearch.index.analysis.AnalysisModule; import org.elasticsearch.index.analysis.AnalysisModule;
import org.elasticsearch.index.analysis.AnalysisService; import org.elasticsearch.index.analysis.AnalysisService;
import org.elasticsearch.index.cache.IndexCache; import org.elasticsearch.index.cache.IndexCache;
@ -330,7 +329,6 @@ public class IndicesService extends AbstractLifecycleComponent<IndicesService> i
ModulesBuilder modules = new ModulesBuilder(); ModulesBuilder modules = new ModulesBuilder();
modules.add(new IndexNameModule(index)); modules.add(new IndexNameModule(index));
modules.add(new LocalNodeIdModule(localNodeId));
modules.add(new IndexSettingsModule(index, indexSettings)); modules.add(new IndexSettingsModule(index, indexSettings));
// plugin modules must be added here, before others or we can get crazy injection errors... // plugin modules must be added here, before others or we can get crazy injection errors...
for (Module pluginModule : pluginsService.indexModules(indexSettings)) { for (Module pluginModule : pluginsService.indexModules(indexSettings)) {
@ -338,7 +336,7 @@ public class IndicesService extends AbstractLifecycleComponent<IndicesService> i
} }
modules.add(new IndexStoreModule(indexSettings)); modules.add(new IndexStoreModule(indexSettings));
modules.add(new AnalysisModule(indexSettings, indicesAnalysisService)); modules.add(new AnalysisModule(indexSettings, indicesAnalysisService));
modules.add(new SimilarityModule(indexSettings)); modules.add(new SimilarityModule(index, indexSettings));
modules.add(new IndexCacheModule(indexSettings)); modules.add(new IndexCacheModule(indexSettings));
modules.add(new IndexModule()); modules.add(new IndexModule());

View File

@ -60,22 +60,6 @@ public abstract class ModuleTestCase extends ESTestCase {
fail("Did not find any binding to " + to.getName() + ". Found these bindings:\n" + s); fail("Did not find any binding to " + to.getName() + ". Found these bindings:\n" + s);
} }
// /** Configures the module and asserts "instance" is bound to "to". */
// public void assertInstanceBinding(Module module, Class to, Object instance) {
// List<Element> elements = Elements.getElements(module);
// for (Element element : elements) {
// if (element instanceof ProviderInstanceBinding) {
// assertEquals(instance, ((ProviderInstanceBinding) element).getProviderInstance().get());
// return;
// }
// }
// StringBuilder s = new StringBuilder();
// for (Element element : elements) {
// s.append(element + "\n");
// }
// fail("Did not find any binding to " + to.getName() + ". Found these bindings:\n" + s);
// }
/** /**
* Attempts to configure the module, and asserts an {@link IllegalArgumentException} is * Attempts to configure the module, and asserts an {@link IllegalArgumentException} is
* caught, containing the given messages * caught, containing the given messages

View File

@ -68,7 +68,7 @@ import org.elasticsearch.index.mapper.internal.SourceFieldMapper;
import org.elasticsearch.index.mapper.internal.UidFieldMapper; import org.elasticsearch.index.mapper.internal.UidFieldMapper;
import org.elasticsearch.index.mapper.object.RootObjectMapper; import org.elasticsearch.index.mapper.object.RootObjectMapper;
import org.elasticsearch.index.shard.*; import org.elasticsearch.index.shard.*;
import org.elasticsearch.index.similarity.SimilarityLookupService; import org.elasticsearch.index.similarity.SimilarityService;
import org.elasticsearch.index.store.DirectoryService; import org.elasticsearch.index.store.DirectoryService;
import org.elasticsearch.index.store.DirectoryUtils; import org.elasticsearch.index.store.DirectoryUtils;
import org.elasticsearch.index.store.Store; import org.elasticsearch.index.store.Store;
@ -1875,10 +1875,10 @@ public class InternalEngineTests extends ESTestCase {
RootObjectMapper.Builder rootBuilder = new RootObjectMapper.Builder("test"); RootObjectMapper.Builder rootBuilder = new RootObjectMapper.Builder("test");
Index index = new Index(indexName); Index index = new Index(indexName);
AnalysisService analysisService = new AnalysisService(index, settings); AnalysisService analysisService = new AnalysisService(index, settings);
SimilarityLookupService similarityLookupService = new SimilarityLookupService(index, settings); SimilarityService similarityService = new SimilarityService(index, settings);
MapperService mapperService = new MapperService(index, settings, analysisService, similarityLookupService, null); MapperService mapperService = new MapperService(index, settings, analysisService, similarityService, null);
DocumentMapper.Builder b = new DocumentMapper.Builder(settings, rootBuilder, mapperService); DocumentMapper.Builder b = new DocumentMapper.Builder(settings, rootBuilder, mapperService);
DocumentMapperParser parser = new DocumentMapperParser(settings, mapperService, analysisService, similarityLookupService, null); DocumentMapperParser parser = new DocumentMapperParser(settings, mapperService, analysisService, similarityService, null);
this.docMapper = b.build(mapperService, parser); this.docMapper = b.build(mapperService, parser);
} }

View File

@ -215,7 +215,7 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
new IndexSettingsModule(index, indexSettings), new IndexSettingsModule(index, indexSettings),
new IndexCacheModule(indexSettings), new IndexCacheModule(indexSettings),
new AnalysisModule(indexSettings, new IndicesAnalysisService(indexSettings)), new AnalysisModule(indexSettings, new IndicesAnalysisService(indexSettings)),
new SimilarityModule(indexSettings), new SimilarityModule(index, indexSettings),
new IndexNameModule(index), new IndexNameModule(index),
new AbstractModule() { new AbstractModule() {
@Override @Override

View File

@ -96,7 +96,7 @@ public class TemplateQueryParserTests extends ESTestCase {
new IndexSettingsModule(index, settings), new IndexSettingsModule(index, settings),
new IndexCacheModule(settings), new IndexCacheModule(settings),
new AnalysisModule(settings, new IndicesAnalysisService(settings)), new AnalysisModule(settings, new IndicesAnalysisService(settings)),
new SimilarityModule(settings), new SimilarityModule(index, settings),
new IndexNameModule(index), new IndexNameModule(index),
new AbstractModule() { new AbstractModule() {
@Override @Override

View File

@ -0,0 +1,117 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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.elasticsearch.index.similarity;
import org.apache.lucene.index.FieldInvertState;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.search.CollectionStatistics;
import org.apache.lucene.search.TermStatistics;
import org.apache.lucene.search.similarities.BM25Similarity;
import org.apache.lucene.search.similarities.Similarity;
import org.elasticsearch.common.inject.ModuleTestCase;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.Index;
import java.io.IOException;
public class SimilarityModuleTests extends ModuleTestCase {
public void testAddSimilarity() {
Settings indexSettings = Settings.settingsBuilder()
.put("index.similarity.my_similarity.type", "test_similarity")
.put("index.similarity.my_similarity.key", "there is a key")
.build();
SimilarityModule module = new SimilarityModule(new Index("foo"), indexSettings);
module.addSimilarity("test_similarity", (string, settings) -> new SimilarityProvider() {
@Override
public String name() {
return string;
}
@Override
public Similarity get() {
return new TestSimilarity(settings.get("key"));
}
});
assertInstanceBinding(module, SimilarityService.class, (inst) -> {
if (inst instanceof SimilarityService) {
assertNotNull(inst.getSimilarity("my_similarity"));
assertTrue(inst.getSimilarity("my_similarity").get() instanceof TestSimilarity);
assertEquals("my_similarity", inst.getSimilarity("my_similarity").name());
assertEquals("there is a key" , ((TestSimilarity)inst.getSimilarity("my_similarity").get()).key);
return true;
}
return false;
});
}
public void testSetupUnknownSimilarity() {
Settings indexSettings = Settings.settingsBuilder()
.put("index.similarity.my_similarity.type", "test_similarity")
.build();
SimilarityModule module = new SimilarityModule(new Index("foo"), indexSettings);
try {
assertInstanceBinding(module, SimilarityService.class, (inst) -> inst instanceof SimilarityService);
} catch (IllegalArgumentException ex) {
assertEquals("Unknown Similarity type [test_similarity] for [my_similarity]", ex.getMessage());
}
}
public void testSetupWithoutType() {
Settings indexSettings = Settings.settingsBuilder()
.put("index.similarity.my_similarity.foo", "bar")
.build();
SimilarityModule module = new SimilarityModule(new Index("foo"), indexSettings);
try {
assertInstanceBinding(module, SimilarityService.class, (inst) -> inst instanceof SimilarityService);
} catch (IllegalArgumentException ex) {
assertEquals("Similarity [my_similarity] must have an associated type", ex.getMessage());
}
}
private static class TestSimilarity extends Similarity {
private final Similarity delegate = new BM25Similarity();
private final String key;
public TestSimilarity(String key) {
if (key == null) {
throw new AssertionError("key is null");
}
this.key = key;
}
@Override
public long computeNorm(FieldInvertState state) {
return delegate.computeNorm(state);
}
@Override
public SimWeight computeWeight(CollectionStatistics collectionStats, TermStatistics... termStats) {
return delegate.computeWeight(collectionStats, termStats);
}
@Override
public SimScorer simScorer(SimWeight weight, LeafReaderContext context) throws IOException {
return delegate.simScorer(weight, context);
}
}
}

View File

@ -22,6 +22,7 @@ package org.elasticsearch.index.similarity;
import org.apache.lucene.search.similarities.*; import org.apache.lucene.search.similarities.*;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.mapper.DocumentMapper; import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.test.ESSingleNodeTestCase; import org.elasticsearch.test.ESSingleNodeTestCase;
import org.junit.Test; import org.junit.Test;
@ -35,11 +36,9 @@ public class SimilarityTests extends ESSingleNodeTestCase {
@Test @Test
public void testResolveDefaultSimilarities() { public void testResolveDefaultSimilarities() {
SimilarityLookupService similarityLookupService = createIndex("foo").similarityService().similarityLookupService(); SimilarityService similarityService = createIndex("foo").similarityService();
assertThat(similarityLookupService.similarity("default"), instanceOf(PreBuiltSimilarityProvider.class)); assertThat(similarityService.getSimilarity("default").get(), instanceOf(DefaultSimilarity.class));
assertThat(similarityLookupService.similarity("default").get(), instanceOf(DefaultSimilarity.class)); assertThat(similarityService.getSimilarity("BM25").get(), instanceOf(BM25Similarity.class));
assertThat(similarityLookupService.similarity("BM25"), instanceOf(PreBuiltSimilarityProvider.class));
assertThat(similarityLookupService.similarity("BM25").get(), instanceOf(BM25Similarity.class));
} }
@Test @Test
@ -54,8 +53,8 @@ public class SimilarityTests extends ESSingleNodeTestCase {
.put("index.similarity.my_similarity.type", "default") .put("index.similarity.my_similarity.type", "default")
.put("index.similarity.my_similarity.discount_overlaps", false) .put("index.similarity.my_similarity.discount_overlaps", false)
.build(); .build();
SimilarityService similarityService = createIndex("foo", indexSettings).similarityService(); IndexService indexService = createIndex("foo", indexSettings);
DocumentMapper documentMapper = similarityService.mapperService().documentMapperParser().parse(mapping); DocumentMapper documentMapper = indexService.mapperService().documentMapperParser().parse(mapping);
assertThat(documentMapper.mappers().getMapper("field1").fieldType().similarity(), instanceOf(DefaultSimilarityProvider.class)); assertThat(documentMapper.mappers().getMapper("field1").fieldType().similarity(), instanceOf(DefaultSimilarityProvider.class));
DefaultSimilarity similarity = (DefaultSimilarity) documentMapper.mappers().getMapper("field1").fieldType().similarity().get(); DefaultSimilarity similarity = (DefaultSimilarity) documentMapper.mappers().getMapper("field1").fieldType().similarity().get();
@ -76,8 +75,8 @@ public class SimilarityTests extends ESSingleNodeTestCase {
.put("index.similarity.my_similarity.b", 1.5f) .put("index.similarity.my_similarity.b", 1.5f)
.put("index.similarity.my_similarity.discount_overlaps", false) .put("index.similarity.my_similarity.discount_overlaps", false)
.build(); .build();
SimilarityService similarityService = createIndex("foo", indexSettings).similarityService(); IndexService indexService = createIndex("foo", indexSettings);
DocumentMapper documentMapper = similarityService.mapperService().documentMapperParser().parse(mapping); DocumentMapper documentMapper = indexService.mapperService().documentMapperParser().parse(mapping);
assertThat(documentMapper.mappers().getMapper("field1").fieldType().similarity(), instanceOf(BM25SimilarityProvider.class)); assertThat(documentMapper.mappers().getMapper("field1").fieldType().similarity(), instanceOf(BM25SimilarityProvider.class));
BM25Similarity similarity = (BM25Similarity) documentMapper.mappers().getMapper("field1").fieldType().similarity().get(); BM25Similarity similarity = (BM25Similarity) documentMapper.mappers().getMapper("field1").fieldType().similarity().get();
@ -101,8 +100,8 @@ public class SimilarityTests extends ESSingleNodeTestCase {
.put("index.similarity.my_similarity.normalization", "h2") .put("index.similarity.my_similarity.normalization", "h2")
.put("index.similarity.my_similarity.normalization.h2.c", 3f) .put("index.similarity.my_similarity.normalization.h2.c", 3f)
.build(); .build();
SimilarityService similarityService = createIndex("foo", indexSettings).similarityService(); IndexService indexService = createIndex("foo", indexSettings);
DocumentMapper documentMapper = similarityService.mapperService().documentMapperParser().parse(mapping); DocumentMapper documentMapper = indexService.mapperService().documentMapperParser().parse(mapping);
assertThat(documentMapper.mappers().getMapper("field1").fieldType().similarity(), instanceOf(DFRSimilarityProvider.class)); assertThat(documentMapper.mappers().getMapper("field1").fieldType().similarity(), instanceOf(DFRSimilarityProvider.class));
DFRSimilarity similarity = (DFRSimilarity) documentMapper.mappers().getMapper("field1").fieldType().similarity().get(); DFRSimilarity similarity = (DFRSimilarity) documentMapper.mappers().getMapper("field1").fieldType().similarity().get();
@ -127,8 +126,8 @@ public class SimilarityTests extends ESSingleNodeTestCase {
.put("index.similarity.my_similarity.normalization", "h2") .put("index.similarity.my_similarity.normalization", "h2")
.put("index.similarity.my_similarity.normalization.h2.c", 3f) .put("index.similarity.my_similarity.normalization.h2.c", 3f)
.build(); .build();
SimilarityService similarityService = createIndex("foo", indexSettings).similarityService(); IndexService indexService = createIndex("foo", indexSettings);
DocumentMapper documentMapper = similarityService.mapperService().documentMapperParser().parse(mapping); DocumentMapper documentMapper = indexService.mapperService().documentMapperParser().parse(mapping);
assertThat(documentMapper.mappers().getMapper("field1").fieldType().similarity(), instanceOf(IBSimilarityProvider.class)); assertThat(documentMapper.mappers().getMapper("field1").fieldType().similarity(), instanceOf(IBSimilarityProvider.class));
IBSimilarity similarity = (IBSimilarity) documentMapper.mappers().getMapper("field1").fieldType().similarity().get(); IBSimilarity similarity = (IBSimilarity) documentMapper.mappers().getMapper("field1").fieldType().similarity().get();
@ -150,8 +149,8 @@ public class SimilarityTests extends ESSingleNodeTestCase {
.put("index.similarity.my_similarity.type", "LMDirichlet") .put("index.similarity.my_similarity.type", "LMDirichlet")
.put("index.similarity.my_similarity.mu", 3000f) .put("index.similarity.my_similarity.mu", 3000f)
.build(); .build();
SimilarityService similarityService = createIndex("foo", indexSettings).similarityService(); IndexService indexService = createIndex("foo", indexSettings);
DocumentMapper documentMapper = similarityService.mapperService().documentMapperParser().parse(mapping); DocumentMapper documentMapper = indexService.mapperService().documentMapperParser().parse(mapping);
assertThat(documentMapper.mappers().getMapper("field1").fieldType().similarity(), instanceOf(LMDirichletSimilarityProvider.class)); assertThat(documentMapper.mappers().getMapper("field1").fieldType().similarity(), instanceOf(LMDirichletSimilarityProvider.class));
LMDirichletSimilarity similarity = (LMDirichletSimilarity) documentMapper.mappers().getMapper("field1").fieldType().similarity().get(); LMDirichletSimilarity similarity = (LMDirichletSimilarity) documentMapper.mappers().getMapper("field1").fieldType().similarity().get();
@ -170,8 +169,8 @@ public class SimilarityTests extends ESSingleNodeTestCase {
.put("index.similarity.my_similarity.type", "LMJelinekMercer") .put("index.similarity.my_similarity.type", "LMJelinekMercer")
.put("index.similarity.my_similarity.lambda", 0.7f) .put("index.similarity.my_similarity.lambda", 0.7f)
.build(); .build();
SimilarityService similarityService = createIndex("foo", indexSettings).similarityService(); IndexService indexService = createIndex("foo", indexSettings);
DocumentMapper documentMapper = similarityService.mapperService().documentMapperParser().parse(mapping); DocumentMapper documentMapper = indexService.mapperService().documentMapperParser().parse(mapping);
assertThat(documentMapper.mappers().getMapper("field1").fieldType().similarity(), instanceOf(LMJelinekMercerSimilarityProvider.class)); assertThat(documentMapper.mappers().getMapper("field1").fieldType().similarity(), instanceOf(LMJelinekMercerSimilarityProvider.class));
LMJelinekMercerSimilarity similarity = (LMJelinekMercerSimilarity) documentMapper.mappers().getMapper("field1").fieldType().similarity().get(); LMJelinekMercerSimilarity similarity = (LMJelinekMercerSimilarity) documentMapper.mappers().getMapper("field1").fieldType().similarity().get();

View File

@ -30,7 +30,6 @@ import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.not;
public class SimilarityIT extends ESIntegTestCase { public class SimilarityIT extends ESIntegTestCase {
@Test @Test
public void testCustomBM25Similarity() throws Exception { public void testCustomBM25Similarity() throws Exception {