
org.elasticsearch.search.highlight.HighlightBuilder Maven / Gradle / Ivy
/*
* 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.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleSpanFragmenter;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import static com.google.common.collect.Lists.newArrayList;
/**
* A builder for search highlighting. Settings can control how large fields
* are summarized to show only selected snippets ("fragments") containing search terms.
*
* @see org.elasticsearch.search.builder.SearchSourceBuilder#highlight()
*/
public class HighlightBuilder implements ToXContent {
private List fields;
private String tagsSchema;
private Boolean highlightFilter;
private Integer fragmentSize;
private Integer numOfFragments;
private String[] preTags;
private String[] postTags;
private String order;
private String encoder;
private Boolean requireFieldMatch;
private Integer boundaryMaxScan;
private char[] boundaryChars;
private String highlighterType;
private String fragmenter;
private QueryBuilder highlightQuery;
private Integer noMatchSize;
private Integer phraseLimit;
private Map options;
private Boolean forceSource;
private boolean useExplicitFieldOrder = false;
/**
* Adds a field to be highlighted with default fragment size of 100 characters, and
* default number of fragments of 5 using the default encoder
*
* @param name The field to highlight
*/
public HighlightBuilder field(String name) {
if (fields == null) {
fields = newArrayList();
}
fields.add(new Field(name));
return this;
}
/**
* Adds a field to be highlighted with a provided fragment size (in characters), and
* default number of fragments of 5.
*
* @param name The field to highlight
* @param fragmentSize The size of a fragment in characters
*/
public HighlightBuilder field(String name, int fragmentSize) {
if (fields == null) {
fields = newArrayList();
}
fields.add(new Field(name).fragmentSize(fragmentSize));
return this;
}
/**
* Adds a field to be highlighted with a provided fragment size (in characters), and
* a provided (maximum) number of fragments.
*
* @param name The field to highlight
* @param fragmentSize The size of a fragment in characters
* @param numberOfFragments The (maximum) number of fragments
*/
public HighlightBuilder field(String name, int fragmentSize, int numberOfFragments) {
if (fields == null) {
fields = newArrayList();
}
fields.add(new Field(name).fragmentSize(fragmentSize).numOfFragments(numberOfFragments));
return this;
}
/**
* Adds a field to be highlighted with a provided fragment size (in characters), and
* a provided (maximum) number of fragments.
*
* @param name The field to highlight
* @param fragmentSize The size of a fragment in characters
* @param numberOfFragments The (maximum) number of fragments
* @param fragmentOffset The offset from the start of the fragment to the start of the highlight
*/
public HighlightBuilder field(String name, int fragmentSize, int numberOfFragments, int fragmentOffset) {
if (fields == null) {
fields = newArrayList();
}
fields.add(new Field(name).fragmentSize(fragmentSize).numOfFragments(numberOfFragments)
.fragmentOffset(fragmentOffset));
return this;
}
public HighlightBuilder field(Field field) {
if (fields == null) {
fields = newArrayList();
}
fields.add(field);
return this;
}
/**
* Set a tag scheme that encapsulates a built in pre and post tags. The allows schemes
* are styled and default.
*
* @param schemaName The tag scheme name
*/
public HighlightBuilder tagsSchema(String schemaName) {
this.tagsSchema = schemaName;
return this;
}
/**
* Set this to true when using the highlighterType fast-vector-highlighter
* and you want to provide highlighting on filter clauses in your
* query. Default is false.
*/
public HighlightBuilder highlightFilter(boolean highlightFilter) {
this.highlightFilter = highlightFilter;
return this;
}
/**
* Sets the size of a fragment in characters (defaults to 100)
*/
public HighlightBuilder fragmentSize(Integer fragmentSize) {
this.fragmentSize = fragmentSize;
return this;
}
/**
* Sets the maximum number of fragments returned
*/
public HighlightBuilder numOfFragments(Integer numOfFragments) {
this.numOfFragments = numOfFragments;
return this;
}
/**
* Set encoder for the highlighting
* are styled and default.
*
* @param encoder name
*/
public HighlightBuilder encoder(String encoder) {
this.encoder = encoder;
return this;
}
/**
* Explicitly set the pre tags that will be used for highlighting.
*/
public HighlightBuilder preTags(String... preTags) {
this.preTags = preTags;
return this;
}
/**
* Explicitly set the post tags that will be used for highlighting.
*/
public HighlightBuilder postTags(String... postTags) {
this.postTags = postTags;
return this;
}
/**
* The order of fragments per field. By default, ordered by the order in the
* highlighted text. Can be score, which then it will be ordered
* by score of the fragments.
*/
public HighlightBuilder order(String order) {
this.order = order;
return this;
}
/**
* Set to true to cause a field to be highlighted only if a query matches that field.
* Default is false meaning that terms are highlighted on all requested fields regardless
* if the query matches specifically on them.
*/
public HighlightBuilder requireFieldMatch(boolean requireFieldMatch) {
this.requireFieldMatch = requireFieldMatch;
return this;
}
/**
* When using the highlighterType fast-vector-highlighter this setting
* controls how far to look for boundary characters, and defaults to 20.
*/
public HighlightBuilder boundaryMaxScan(Integer boundaryMaxScan) {
this.boundaryMaxScan = boundaryMaxScan;
return this;
}
/**
* When using the highlighterType fast-vector-highlighter this setting
* defines what constitutes a boundary for highlighting. It’s a single string with
* each boundary character defined in it. It defaults to .,!? \t\n
*/
public HighlightBuilder boundaryChars(char[] boundaryChars) {
this.boundaryChars = boundaryChars;
return this;
}
/**
* Set type of highlighter to use. Supported types
* are highlighter, fast-vector-highlighter and postings-highlighter.
* The default option selected is dependent on the mappings defined for your index.
* Details of the different highlighter types are covered in the reference guide.
*/
public HighlightBuilder highlighterType(String highlighterType) {
this.highlighterType = highlighterType;
return this;
}
/**
* Sets what fragmenter to use to break up text that is eligible for highlighting.
* This option is only applicable when using the plain highlighterType highlighter.
* Permitted values are "simple" or "span" relating to {@link SimpleFragmenter} and
* {@link SimpleSpanFragmenter} implementations respectively with the default being "span"
*/
public HighlightBuilder fragmenter(String fragmenter) {
this.fragmenter = fragmenter;
return this;
}
/**
* Sets a query to be used for highlighting all fields instead of the search query.
*/
public HighlightBuilder highlightQuery(QueryBuilder highlightQuery) {
this.highlightQuery = highlightQuery;
return this;
}
/**
* Sets the size of the fragment to return from the beginning of the field if there are no matches to
* highlight and the field doesn't also define noMatchSize.
* @param noMatchSize integer to set or null to leave out of request. default is null.
* @return this for chaining
*/
public HighlightBuilder noMatchSize(Integer noMatchSize) {
this.noMatchSize = noMatchSize;
return this;
}
/**
* Sets the maximum number of phrases the fvh will consider if the field doesn't also define phraseLimit.
* @param phraseLimit maximum number of phrases the fvh will consider
* @return this for chaining
*/
public HighlightBuilder phraseLimit(Integer phraseLimit) {
this.phraseLimit = phraseLimit;
return this;
}
/**
* Allows to set custom options for custom highlighters.
*/
public HighlightBuilder options(Map options) {
this.options = options;
return this;
}
/**
* Forces the highlighting to highlight fields based on the source even if fields are stored separately.
*/
public HighlightBuilder forceSource(boolean forceSource) {
this.forceSource = forceSource;
return this;
}
/**
* Send the fields to be highlighted using a syntax that is specific about the order in which they should be highlighted.
* @return this for chaining
*/
public HighlightBuilder useExplicitFieldOrder(boolean useExplicitFieldOrder) {
this.useExplicitFieldOrder = useExplicitFieldOrder;
return this;
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject("highlight");
if (tagsSchema != null) {
builder.field("tags_schema", tagsSchema);
}
if (preTags != null) {
builder.array("pre_tags", preTags);
}
if (postTags != null) {
builder.array("post_tags", postTags);
}
if (order != null) {
builder.field("order", order);
}
if (highlightFilter != null) {
builder.field("highlight_filter", highlightFilter);
}
if (fragmentSize != null) {
builder.field("fragment_size", fragmentSize);
}
if (numOfFragments != null) {
builder.field("number_of_fragments", numOfFragments);
}
if (encoder != null) {
builder.field("encoder", encoder);
}
if (requireFieldMatch != null) {
builder.field("require_field_match", requireFieldMatch);
}
if (boundaryMaxScan != null) {
builder.field("boundary_max_scan", boundaryMaxScan);
}
if (boundaryChars != null) {
builder.field("boundary_chars", boundaryChars);
}
if (highlighterType != null) {
builder.field("type", highlighterType);
}
if (fragmenter != null) {
builder.field("fragmenter", fragmenter);
}
if (highlightQuery != null) {
builder.field("highlight_query", highlightQuery);
}
if (noMatchSize != null) {
builder.field("no_match_size", noMatchSize);
}
if (phraseLimit != null) {
builder.field("phrase_limit", phraseLimit);
}
if (options != null && options.size() > 0) {
builder.field("options", options);
}
if (forceSource != null) {
builder.field("force_source", forceSource);
}
if (fields != null) {
if (useExplicitFieldOrder) {
builder.startArray("fields");
} else {
builder.startObject("fields");
}
for (Field field : fields) {
if (useExplicitFieldOrder) {
builder.startObject();
}
builder.startObject(field.name());
if (field.preTags != null) {
builder.field("pre_tags", field.preTags);
}
if (field.postTags != null) {
builder.field("post_tags", field.postTags);
}
if (field.fragmentSize != -1) {
builder.field("fragment_size", field.fragmentSize);
}
if (field.numOfFragments != -1) {
builder.field("number_of_fragments", field.numOfFragments);
}
if (field.fragmentOffset != -1) {
builder.field("fragment_offset", field.fragmentOffset);
}
if (field.highlightFilter != null) {
builder.field("highlight_filter", field.highlightFilter);
}
if (field.order != null) {
builder.field("order", field.order);
}
if (field.requireFieldMatch != null) {
builder.field("require_field_match", field.requireFieldMatch);
}
if (field.boundaryMaxScan != -1) {
builder.field("boundary_max_scan", field.boundaryMaxScan);
}
if (field.boundaryChars != null) {
builder.field("boundary_chars", field.boundaryChars);
}
if (field.highlighterType != null) {
builder.field("type", field.highlighterType);
}
if (field.fragmenter != null) {
builder.field("fragmenter", field.fragmenter);
}
if (field.highlightQuery != null) {
builder.field("highlight_query", field.highlightQuery);
}
if (field.noMatchSize != null) {
builder.field("no_match_size", field.noMatchSize);
}
if (field.matchedFields != null) {
builder.field("matched_fields", field.matchedFields);
}
if (field.phraseLimit != null) {
builder.field("phrase_limit", field.phraseLimit);
}
if (field.options != null && field.options.size() > 0) {
builder.field("options", field.options);
}
if (field.forceSource != null) {
builder.field("force_source", field.forceSource);
}
builder.endObject();
if (useExplicitFieldOrder) {
builder.endObject();
}
}
if (useExplicitFieldOrder) {
builder.endArray();
} else {
builder.endObject();
}
}
builder.endObject();
return builder;
}
public static class Field {
final String name;
String[] preTags;
String[] postTags;
int fragmentSize = -1;
int fragmentOffset = -1;
int numOfFragments = -1;
Boolean highlightFilter;
String order;
Boolean requireFieldMatch;
int boundaryMaxScan = -1;
char[] boundaryChars;
String highlighterType;
String fragmenter;
QueryBuilder highlightQuery;
Integer noMatchSize;
String[] matchedFields;
Integer phraseLimit;
Map options;
Boolean forceSource;
public Field(String name) {
this.name = name;
}
public String name() {
return name;
}
/**
* Explicitly set the pre tags for this field that will be used for highlighting.
* This overrides global settings set by {@link HighlightBuilder#preTags(String...)}.
*/
public Field preTags(String... preTags) {
this.preTags = preTags;
return this;
}
/**
* Explicitly set the post tags for this field that will be used for highlighting.
* This overrides global settings set by {@link HighlightBuilder#postTags(String...)}.
*/
public Field postTags(String... postTags) {
this.postTags = postTags;
return this;
}
public Field fragmentSize(int fragmentSize) {
this.fragmentSize = fragmentSize;
return this;
}
public Field fragmentOffset(int fragmentOffset) {
this.fragmentOffset = fragmentOffset;
return this;
}
public Field numOfFragments(int numOfFragments) {
this.numOfFragments = numOfFragments;
return this;
}
public Field highlightFilter(boolean highlightFilter) {
this.highlightFilter = highlightFilter;
return this;
}
/**
* The order of fragments per field. By default, ordered by the order in the
* highlighted text. Can be score, which then it will be ordered
* by score of the fragments.
* This overrides global settings set by {@link HighlightBuilder#order(String)}.
*/
public Field order(String order) {
this.order = order;
return this;
}
public Field requireFieldMatch(boolean requireFieldMatch) {
this.requireFieldMatch = requireFieldMatch;
return this;
}
public Field boundaryMaxScan(int boundaryMaxScan) {
this.boundaryMaxScan = boundaryMaxScan;
return this;
}
public Field boundaryChars(char[] boundaryChars) {
this.boundaryChars = boundaryChars;
return this;
}
/**
* Set type of highlighter to use. Supported types
* are highlighter, fast-vector-highlighter nad postings-highlighter.
* This overrides global settings set by {@link HighlightBuilder#highlighterType(String)}.
*/
public Field highlighterType(String highlighterType) {
this.highlighterType = highlighterType;
return this;
}
/**
* Sets what fragmenter to use to break up text that is eligible for highlighting.
* This option is only applicable when using plain / normal highlighter.
* This overrides global settings set by {@link HighlightBuilder#fragmenter(String)}.
*/
public Field fragmenter(String fragmenter) {
this.fragmenter = fragmenter;
return this;
}
/**
* Sets a query to use for highlighting this field instead of the search query.
*/
public Field highlightQuery(QueryBuilder highlightQuery) {
this.highlightQuery = highlightQuery;
return this;
}
/**
* Sets the size of the fragment to return from the beginning of the field if there are no matches to
* highlight.
* @param noMatchSize integer to set or null to leave out of request. default is null.
* @return this for chaining
*/
public Field noMatchSize(Integer noMatchSize) {
this.noMatchSize = noMatchSize;
return this;
}
/**
* Allows to set custom options for custom highlighters.
* This overrides global settings set by {@link HighlightBuilder#options(Map)}.
*/
public Field options(Map options) {
this.options = options;
return this;
}
/**
* Set the matched fields to highlight against this field data. Default to null, meaning just
* the named field. If you provide a list of fields here then don't forget to include name as
* it is not automatically included.
*/
public Field matchedFields(String... matchedFields) {
this.matchedFields = matchedFields;
return this;
}
/**
* Sets the maximum number of phrases the fvh will consider.
* @param phraseLimit maximum number of phrases the fvh will consider
* @return this for chaining
*/
public Field phraseLimit(Integer phraseLimit) {
this.phraseLimit = phraseLimit;
return this;
}
/**
* Forces the highlighting to highlight this field based on the source even if this field is stored separately.
*/
public Field forceSource(boolean forceSource) {
this.forceSource = forceSource;
return this;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy