Register Highlighter instances instead of classes (#18859)
This change detaches highlighter registration from Guice. It's just a small step into the right direction.
This commit is contained in:
parent
d7e3f9e4eb
commit
ee2ba13cce
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* 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.search;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.search.highlight.FastVectorHighlighter;
|
||||||
|
import org.elasticsearch.search.highlight.Highlighter;
|
||||||
|
import org.elasticsearch.search.highlight.PlainHighlighter;
|
||||||
|
import org.elasticsearch.search.highlight.PostingsHighlighter;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An extensions point and registry for all the highlighters a node supports.
|
||||||
|
*/
|
||||||
|
public final class Highlighters {
|
||||||
|
|
||||||
|
private final Map<String, Highlighter> parsers = new HashMap<>();
|
||||||
|
|
||||||
|
Highlighters(Settings settings) {
|
||||||
|
registerHighlighter("fvh", new FastVectorHighlighter(settings));
|
||||||
|
registerHighlighter("plain", new PlainHighlighter());
|
||||||
|
registerHighlighter("postings", new PostingsHighlighter());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the highlighter for the given key or <code>null</code> if there is no highlighter registered for that key.
|
||||||
|
*/
|
||||||
|
public Highlighter get(String key) {
|
||||||
|
return parsers.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a highlighter for the given key
|
||||||
|
* @param key the key the highlighter should be referenced by in the search request
|
||||||
|
* @param highlighter the highlighter instance
|
||||||
|
*/
|
||||||
|
void registerHighlighter(String key, Highlighter highlighter) {
|
||||||
|
if (highlighter == null) {
|
||||||
|
throw new IllegalArgumentException("Can't register null highlighter for key: [" + key + "]");
|
||||||
|
}
|
||||||
|
if (parsers.putIfAbsent(key, highlighter) != null) {
|
||||||
|
throw new IllegalArgumentException("Can't register the same [highlighter] more than once for [" + key + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,7 +28,6 @@ import org.elasticsearch.common.inject.multibindings.Multibinder;
|
||||||
import org.elasticsearch.common.io.stream.NamedWriteable;
|
import org.elasticsearch.common.io.stream.NamedWriteable;
|
||||||
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
|
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
|
||||||
import org.elasticsearch.common.io.stream.Writeable;
|
import org.elasticsearch.common.io.stream.Writeable;
|
||||||
import org.elasticsearch.common.lucene.search.function.ScoreFunction;
|
|
||||||
import org.elasticsearch.common.settings.Setting;
|
import org.elasticsearch.common.settings.Setting;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.ParseFieldRegistry;
|
import org.elasticsearch.common.xcontent.ParseFieldRegistry;
|
||||||
|
@ -250,7 +249,6 @@ import org.elasticsearch.search.fetch.source.FetchSourceSubPhase;
|
||||||
import org.elasticsearch.search.fetch.version.VersionFetchSubPhase;
|
import org.elasticsearch.search.fetch.version.VersionFetchSubPhase;
|
||||||
import org.elasticsearch.search.highlight.HighlightPhase;
|
import org.elasticsearch.search.highlight.HighlightPhase;
|
||||||
import org.elasticsearch.search.highlight.Highlighter;
|
import org.elasticsearch.search.highlight.Highlighter;
|
||||||
import org.elasticsearch.search.highlight.Highlighters;
|
|
||||||
import org.elasticsearch.search.query.QueryPhase;
|
import org.elasticsearch.search.query.QueryPhase;
|
||||||
import org.elasticsearch.search.rescore.QueryRescorerBuilder;
|
import org.elasticsearch.search.rescore.QueryRescorerBuilder;
|
||||||
import org.elasticsearch.search.rescore.RescoreBuilder;
|
import org.elasticsearch.search.rescore.RescoreBuilder;
|
||||||
|
@ -270,9 +268,8 @@ import java.util.Set;
|
||||||
*/
|
*/
|
||||||
public class SearchModule extends AbstractModule {
|
public class SearchModule extends AbstractModule {
|
||||||
|
|
||||||
private final Highlighters highlighters = new Highlighters();
|
private final Highlighters highlighters;
|
||||||
private final Suggesters suggesters;
|
private final Suggesters suggesters;
|
||||||
|
|
||||||
private final ParseFieldRegistry<ScoreFunctionParser<?>> scoreFunctionParserRegistry = new ParseFieldRegistry<>("score_function");
|
private final ParseFieldRegistry<ScoreFunctionParser<?>> scoreFunctionParserRegistry = new ParseFieldRegistry<>("score_function");
|
||||||
private final IndicesQueriesRegistry queryParserRegistry = new IndicesQueriesRegistry();
|
private final IndicesQueriesRegistry queryParserRegistry = new IndicesQueriesRegistry();
|
||||||
private final ParseFieldRegistry<Aggregator.Parser> aggregationParserRegistry = new ParseFieldRegistry<>("aggregation");
|
private final ParseFieldRegistry<Aggregator.Parser> aggregationParserRegistry = new ParseFieldRegistry<>("aggregation");
|
||||||
|
@ -298,7 +295,7 @@ public class SearchModule extends AbstractModule {
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
this.namedWriteableRegistry = namedWriteableRegistry;
|
this.namedWriteableRegistry = namedWriteableRegistry;
|
||||||
suggesters = new Suggesters(namedWriteableRegistry);
|
suggesters = new Suggesters(namedWriteableRegistry);
|
||||||
|
highlighters = new Highlighters(settings);
|
||||||
registerBuiltinScoreFunctionParsers();
|
registerBuiltinScoreFunctionParsers();
|
||||||
registerBuiltinQueryParsers();
|
registerBuiltinQueryParsers();
|
||||||
registerBuiltinRescorers();
|
registerBuiltinRescorers();
|
||||||
|
@ -308,8 +305,8 @@ public class SearchModule extends AbstractModule {
|
||||||
registerBuiltinMovingAverageModels();
|
registerBuiltinMovingAverageModels();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerHighlighter(String key, Class<? extends Highlighter> clazz) {
|
public void registerHighlighter(String key, Highlighter highligher) {
|
||||||
highlighters.registerExtension(key, clazz);
|
highlighters.registerHighlighter(key, highligher);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerSuggester(String key, Suggester<?> suggester) {
|
public void registerSuggester(String key, Suggester<?> suggester) {
|
||||||
|
@ -331,13 +328,6 @@ public class SearchModule extends AbstractModule {
|
||||||
namedWriteableRegistry.register(ScoreFunctionBuilder.class, functionName.getPreferredName(), reader);
|
namedWriteableRegistry.register(ScoreFunctionBuilder.class, functionName.getPreferredName(), reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch the registry of {@linkplain ScoreFunction}s. This is public so extensions can access the score functions.
|
|
||||||
*/
|
|
||||||
public ParseFieldRegistry<ScoreFunctionParser<?>> getScoreFunctionParserRegistry() {
|
|
||||||
return scoreFunctionParserRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a new ValueFormat.
|
* Register a new ValueFormat.
|
||||||
*/
|
*/
|
||||||
|
@ -441,10 +431,6 @@ public class SearchModule extends AbstractModule {
|
||||||
namedWriteableRegistry.register(PipelineAggregatorBuilder.class, aggregationName.getPreferredName(), reader);
|
namedWriteableRegistry.register(PipelineAggregatorBuilder.class, aggregationName.getPreferredName(), reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AggregatorParsers getAggregatorParsers() {
|
|
||||||
return aggregatorParsers;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(IndicesQueriesRegistry.class).toInstance(queryParserRegistry);
|
bind(IndicesQueriesRegistry.class).toInstance(queryParserRegistry);
|
||||||
|
@ -473,7 +459,7 @@ public class SearchModule extends AbstractModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void configureHighlighters() {
|
protected void configureHighlighters() {
|
||||||
highlighters.bind(binder());
|
binder().bind(Highlighters.class).toInstance(highlighters);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void configureAggs() {
|
protected void configureAggs() {
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.elasticsearch.index.mapper.core.KeywordFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.core.StringFieldMapper;
|
import org.elasticsearch.index.mapper.core.StringFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.core.TextFieldMapper;
|
import org.elasticsearch.index.mapper.core.TextFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.internal.SourceFieldMapper;
|
import org.elasticsearch.index.mapper.internal.SourceFieldMapper;
|
||||||
|
import org.elasticsearch.search.Highlighters;
|
||||||
import org.elasticsearch.search.SearchParseElement;
|
import org.elasticsearch.search.SearchParseElement;
|
||||||
import org.elasticsearch.search.fetch.FetchSubPhase;
|
import org.elasticsearch.search.fetch.FetchSubPhase;
|
||||||
import org.elasticsearch.search.internal.InternalSearchHit;
|
import org.elasticsearch.search.internal.InternalSearchHit;
|
||||||
|
|
|
@ -1,69 +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.search.highlight;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.util.ExtensionPoint;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An extensions point and registry for all the highlighters a node supports.
|
|
||||||
*/
|
|
||||||
public class Highlighters extends ExtensionPoint.ClassMap<Highlighter> {
|
|
||||||
|
|
||||||
private static final String FVH = "fvh";
|
|
||||||
private static final String PLAIN = "plain";
|
|
||||||
private static final String POSTINGS = "postings";
|
|
||||||
|
|
||||||
private final Map<String, Highlighter> parsers;
|
|
||||||
|
|
||||||
public Highlighters(){
|
|
||||||
this(Collections.emptyMap());
|
|
||||||
}
|
|
||||||
|
|
||||||
private Highlighters(Map<String, Highlighter> parsers) {
|
|
||||||
super("highlighter", Highlighter.class, new HashSet<>(Arrays.asList(FVH, PLAIN, POSTINGS)),
|
|
||||||
Highlighters.class);
|
|
||||||
this.parsers = Collections.unmodifiableMap(parsers);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public Highlighters(Settings settings, Map<String, Highlighter> parsers) {
|
|
||||||
this(addBuiltIns(settings, parsers));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Map<String, Highlighter> addBuiltIns(Settings settings, Map<String, Highlighter> parsers) {
|
|
||||||
Map<String, Highlighter> map = new HashMap<>();
|
|
||||||
map.put(FVH, new FastVectorHighlighter(settings));
|
|
||||||
map.put(PLAIN, new PlainHighlighter());
|
|
||||||
map.put(POSTINGS, new PostingsHighlighter());
|
|
||||||
map.putAll(parsers);
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Highlighter get(String type) {
|
|
||||||
return parsers.get(type);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -29,8 +29,9 @@ import org.elasticsearch.index.query.QueryParser;
|
||||||
import org.elasticsearch.index.query.TermQueryBuilder;
|
import org.elasticsearch.index.query.TermQueryBuilder;
|
||||||
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
|
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
|
||||||
import org.elasticsearch.search.highlight.CustomHighlighter;
|
import org.elasticsearch.search.highlight.CustomHighlighter;
|
||||||
import org.elasticsearch.search.highlight.Highlighter;
|
import org.elasticsearch.search.highlight.FastVectorHighlighter;
|
||||||
import org.elasticsearch.search.highlight.PlainHighlighter;
|
import org.elasticsearch.search.highlight.PlainHighlighter;
|
||||||
|
import org.elasticsearch.search.highlight.PostingsHighlighter;
|
||||||
import org.elasticsearch.search.suggest.CustomSuggester;
|
import org.elasticsearch.search.suggest.CustomSuggester;
|
||||||
import org.elasticsearch.search.suggest.phrase.PhraseSuggester;
|
import org.elasticsearch.search.suggest.phrase.PhraseSuggester;
|
||||||
|
|
||||||
|
@ -48,7 +49,7 @@ public class SearchModuleTests extends ModuleTestCase {
|
||||||
public void testDoubleRegister() {
|
public void testDoubleRegister() {
|
||||||
SearchModule module = new SearchModule(Settings.EMPTY, new NamedWriteableRegistry());
|
SearchModule module = new SearchModule(Settings.EMPTY, new NamedWriteableRegistry());
|
||||||
try {
|
try {
|
||||||
module.registerHighlighter("fvh", PlainHighlighter.class);
|
module.registerHighlighter("fvh", new PlainHighlighter());
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
assertEquals(e.getMessage(), "Can't register the same [highlighter] more than once for [fvh]");
|
assertEquals(e.getMessage(), "Can't register the same [highlighter] more than once for [fvh]");
|
||||||
}
|
}
|
||||||
|
@ -70,13 +71,18 @@ public class SearchModuleTests extends ModuleTestCase {
|
||||||
|
|
||||||
public void testRegisterHighlighter() {
|
public void testRegisterHighlighter() {
|
||||||
SearchModule module = new SearchModule(Settings.EMPTY, new NamedWriteableRegistry());
|
SearchModule module = new SearchModule(Settings.EMPTY, new NamedWriteableRegistry());
|
||||||
module.registerHighlighter("custom", CustomHighlighter.class);
|
module.registerHighlighter("custom", new CustomHighlighter());
|
||||||
try {
|
IllegalArgumentException exception = expectThrows(IllegalArgumentException.class,
|
||||||
module.registerHighlighter("custom", CustomHighlighter.class);
|
() -> module.registerHighlighter("custom", new CustomHighlighter()));
|
||||||
} catch (IllegalArgumentException e) {
|
assertEquals("Can't register the same [highlighter] more than once for [custom]", exception.getMessage());
|
||||||
assertEquals(e.getMessage(), "Can't register the same [highlighter] more than once for [custom]");
|
|
||||||
}
|
exception = expectThrows(IllegalArgumentException.class,
|
||||||
assertMapMultiBinding(module, Highlighter.class, CustomHighlighter.class);
|
() -> module.registerHighlighter("custom", null));
|
||||||
|
assertEquals("Can't register null highlighter for key: [custom]", exception.getMessage());
|
||||||
|
assertInstanceBinding(module, Highlighters.class, (h) -> h.get("custom").getClass() == CustomHighlighter.class
|
||||||
|
&& h.get("fvh").getClass() == FastVectorHighlighter.class
|
||||||
|
&& h.get("plain").getClass() == PlainHighlighter.class
|
||||||
|
&& h.get("postings").getClass() == PostingsHighlighter.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRegisterQueryParserDuplicate() {
|
public void testRegisterQueryParserDuplicate() {
|
||||||
|
|
|
@ -35,6 +35,6 @@ public class CustomHighlighterPlugin extends Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onModule(SearchModule highlightModule) {
|
public void onModule(SearchModule highlightModule) {
|
||||||
highlightModule.registerHighlighter("test-custom", CustomHighlighter.class);
|
highlightModule.registerHighlighter("test-custom", new CustomHighlighter());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue