|
@@ -19,16 +19,19 @@
|
|
|
|
|
|
package org.elasticsearch.search.highlight;
|
|
|
|
|
|
-import org.apache.lucene.search.highlight.SimpleFragmenter;
|
|
|
-import org.apache.lucene.search.highlight.SimpleSpanFragmenter;
|
|
|
+import org.elasticsearch.ExceptionsHelper;
|
|
|
+import org.elasticsearch.common.io.stream.StreamInput;
|
|
|
+import org.elasticsearch.common.io.stream.StreamOutput;
|
|
|
+import org.elasticsearch.common.io.stream.Writeable;
|
|
|
import org.elasticsearch.common.xcontent.ToXContent;
|
|
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
|
-import org.elasticsearch.index.query.QueryBuilder;
|
|
|
+import org.elasticsearch.common.xcontent.XContentFactory;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
import java.util.ArrayList;
|
|
|
+import java.util.Arrays;
|
|
|
import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
+import java.util.Objects;
|
|
|
|
|
|
/**
|
|
|
* A builder for search highlighting. Settings can control how large fields
|
|
@@ -36,46 +39,14 @@ import java.util.Map;
|
|
|
*
|
|
|
* @see org.elasticsearch.search.builder.SearchSourceBuilder#highlight()
|
|
|
*/
|
|
|
-public class HighlightBuilder implements ToXContent {
|
|
|
+public class HighlightBuilder extends AbstractHighlighterBuilder<HighlightBuilder> implements Writeable<HighlightBuilder>, ToXContent {
|
|
|
|
|
|
- private List<Field> fields;
|
|
|
+ public static final HighlightBuilder PROTOTYPE = new HighlightBuilder();
|
|
|
|
|
|
- private String tagsSchema;
|
|
|
-
|
|
|
- private Boolean highlightFilter;
|
|
|
-
|
|
|
- private Integer fragmentSize;
|
|
|
-
|
|
|
- private Integer numOfFragments;
|
|
|
-
|
|
|
- private String[] preTags;
|
|
|
-
|
|
|
- private String[] postTags;
|
|
|
-
|
|
|
- private String order;
|
|
|
+ private final List<Field> fields = new ArrayList<>();
|
|
|
|
|
|
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<String, Object> options;
|
|
|
-
|
|
|
- private Boolean forceSource;
|
|
|
-
|
|
|
private boolean useExplicitFieldOrder = false;
|
|
|
|
|
|
/**
|
|
@@ -85,14 +56,9 @@ public class HighlightBuilder implements ToXContent {
|
|
|
* @param name The field to highlight
|
|
|
*/
|
|
|
public HighlightBuilder field(String name) {
|
|
|
- if (fields == null) {
|
|
|
- fields = new ArrayList<>();
|
|
|
- }
|
|
|
- fields.add(new Field(name));
|
|
|
- return this;
|
|
|
+ return field(new Field(name));
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/**
|
|
|
* Adds a field to be highlighted with a provided fragment size (in characters), and
|
|
|
* default number of fragments of 5.
|
|
@@ -101,11 +67,7 @@ public class HighlightBuilder implements ToXContent {
|
|
|
* @param fragmentSize The size of a fragment in characters
|
|
|
*/
|
|
|
public HighlightBuilder field(String name, int fragmentSize) {
|
|
|
- if (fields == null) {
|
|
|
- fields = new ArrayList<>();
|
|
|
- }
|
|
|
- fields.add(new Field(name).fragmentSize(fragmentSize));
|
|
|
- return this;
|
|
|
+ return field(new Field(name).fragmentSize(fragmentSize));
|
|
|
}
|
|
|
|
|
|
|
|
@@ -118,14 +80,9 @@ public class HighlightBuilder implements ToXContent {
|
|
|
* @param numberOfFragments The (maximum) number of fragments
|
|
|
*/
|
|
|
public HighlightBuilder field(String name, int fragmentSize, int numberOfFragments) {
|
|
|
- if (fields == null) {
|
|
|
- fields = new ArrayList<>();
|
|
|
- }
|
|
|
- fields.add(new Field(name).fragmentSize(fragmentSize).numOfFragments(numberOfFragments));
|
|
|
- return this;
|
|
|
+ return field(new Field(name).fragmentSize(fragmentSize).numOfFragments(numberOfFragments));
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/**
|
|
|
* Adds a field to be highlighted with a provided fragment size (in characters), and
|
|
|
* a provided (maximum) number of fragments.
|
|
@@ -136,56 +93,38 @@ public class HighlightBuilder implements ToXContent {
|
|
|
* @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 = new ArrayList<>();
|
|
|
- }
|
|
|
- fields.add(new Field(name).fragmentSize(fragmentSize).numOfFragments(numberOfFragments)
|
|
|
+ return field(new Field(name).fragmentSize(fragmentSize).numOfFragments(numberOfFragments)
|
|
|
.fragmentOffset(fragmentOffset));
|
|
|
- return this;
|
|
|
}
|
|
|
|
|
|
public HighlightBuilder field(Field field) {
|
|
|
- if (fields == null) {
|
|
|
- fields = new ArrayList<>();
|
|
|
- }
|
|
|
fields.add(field);
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
+ public List<Field> fields() {
|
|
|
+ return this.fields;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
- * Set a tag scheme that encapsulates a built in pre and post tags. The allows schemes
|
|
|
+ * Set a tag scheme that encapsulates a built in pre and post tags. The allowed schemes
|
|
|
* are <tt>styled</tt> and <tt>default</tt>.
|
|
|
*
|
|
|
* @param schemaName The tag scheme name
|
|
|
*/
|
|
|
public HighlightBuilder tagsSchema(String schemaName) {
|
|
|
- this.tagsSchema = schemaName;
|
|
|
- return this;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Set this to true when using the highlighterType <tt>fvh</tt>
|
|
|
- * and you want to provide highlighting on filter clauses in your
|
|
|
- * query. Default is <tt>false</tt>.
|
|
|
- */
|
|
|
- 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;
|
|
|
+ switch (schemaName) {
|
|
|
+ case "default":
|
|
|
+ preTags(HighlighterParseElement.DEFAULT_PRE_TAGS);
|
|
|
+ postTags(HighlighterParseElement.DEFAULT_POST_TAGS);
|
|
|
+ break;
|
|
|
+ case "styled":
|
|
|
+ preTags(HighlighterParseElement.STYLED_PRE_TAG);
|
|
|
+ postTags(HighlighterParseElement.STYLED_POST_TAGS);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ throw new IllegalArgumentException("Unknown tag schema ["+ schemaName +"]");
|
|
|
+ }
|
|
|
return this;
|
|
|
}
|
|
|
|
|
@@ -201,201 +140,44 @@ public class HighlightBuilder implements ToXContent {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Explicitly set the pre tags that will be used for highlighting.
|
|
|
+ * Getter for {@link #encoder(String)}
|
|
|
*/
|
|
|
- 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 <tt>score</tt>, which then it will be ordered
|
|
|
- * by score of the fragments.
|
|
|
- */
|
|
|
- public HighlightBuilder order(String order) {
|
|
|
- this.order = order;
|
|
|
- return this;
|
|
|
+ public String encoder() {
|
|
|
+ return this.encoder;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 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 <tt>fvh</tt> 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 <tt>fvh</tt> 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. Out of the box supported types
|
|
|
- * are <tt>plain</tt>, <tt>fvh</tt> and <tt>postings</tt>.
|
|
|
- * 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 <tt>highlighter</tt>.
|
|
|
- * 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
|
|
|
+ * 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 phraseLimit(Integer phraseLimit) {
|
|
|
- this.phraseLimit = phraseLimit;
|
|
|
- return this;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Allows to set custom options for custom highlighters.
|
|
|
- */
|
|
|
- public HighlightBuilder options(Map<String, Object> 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;
|
|
|
+ public HighlightBuilder useExplicitFieldOrder(boolean useExplicitFieldOrder) {
|
|
|
+ this.useExplicitFieldOrder = useExplicitFieldOrder;
|
|
|
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
|
|
|
+ * Gets value set with {@link #useExplicitFieldOrder(boolean)}
|
|
|
*/
|
|
|
- public HighlightBuilder useExplicitFieldOrder(boolean useExplicitFieldOrder) {
|
|
|
- this.useExplicitFieldOrder = useExplicitFieldOrder;
|
|
|
- return this;
|
|
|
+ public Boolean useExplicitFieldOrder() {
|
|
|
+ return this.useExplicitFieldOrder;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
|
|
builder.startObject("highlight");
|
|
|
- innerXContent(builder, params);
|
|
|
+ innerXContent(builder);
|
|
|
builder.endObject();
|
|
|
return builder;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- public void innerXContent(XContentBuilder builder, Params params) throws IOException {
|
|
|
- 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);
|
|
|
- }
|
|
|
+ public void innerXContent(XContentBuilder builder) throws IOException {
|
|
|
+ // first write common options
|
|
|
+ commonOptionsToXContent(builder);
|
|
|
+ // special options for top-level highlighter
|
|
|
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 (fields.size() > 0) {
|
|
|
if (useExplicitFieldOrder) {
|
|
|
builder.startArray("fields");
|
|
|
} else {
|
|
@@ -405,63 +187,7 @@ public class HighlightBuilder implements ToXContent {
|
|
|
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();
|
|
|
+ field.innerXContent(builder);
|
|
|
if (useExplicitFieldOrder) {
|
|
|
builder.endObject();
|
|
|
}
|
|
@@ -474,144 +200,73 @@ public class HighlightBuilder implements ToXContent {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- 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<String, Object> 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;
|
|
|
+ @Override
|
|
|
+ public final String toString() {
|
|
|
+ try {
|
|
|
+ XContentBuilder builder = XContentFactory.jsonBuilder();
|
|
|
+ builder.prettyPrint();
|
|
|
+ toXContent(builder, ToXContent.EMPTY_PARAMS);
|
|
|
+ return builder.string();
|
|
|
+ } catch (Exception e) {
|
|
|
+ return "{ \"error\" : \"" + ExceptionsHelper.detailedMessage(e) + "\"}";
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- public Field numOfFragments(int numOfFragments) {
|
|
|
- this.numOfFragments = numOfFragments;
|
|
|
- return this;
|
|
|
- }
|
|
|
+ @Override
|
|
|
+ protected int doHashCode() {
|
|
|
+ return Objects.hash(encoder, useExplicitFieldOrder, fields);
|
|
|
+ }
|
|
|
|
|
|
- public Field highlightFilter(boolean highlightFilter) {
|
|
|
- this.highlightFilter = highlightFilter;
|
|
|
- return this;
|
|
|
- }
|
|
|
+ @Override
|
|
|
+ protected boolean doEquals(HighlightBuilder other) {
|
|
|
+ return Objects.equals(encoder, other.encoder) &&
|
|
|
+ Objects.equals(useExplicitFieldOrder, other.useExplicitFieldOrder) &&
|
|
|
+ Objects.equals(fields, other.fields);
|
|
|
+ }
|
|
|
|
|
|
- /**
|
|
|
- * The order of fragments per field. By default, ordered by the order in the
|
|
|
- * highlighted text. Can be <tt>score</tt>, 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;
|
|
|
- }
|
|
|
+ @Override
|
|
|
+ public HighlightBuilder readFrom(StreamInput in) throws IOException {
|
|
|
+ HighlightBuilder highlightBuilder = new HighlightBuilder();
|
|
|
+ highlightBuilder.readOptionsFrom(in)
|
|
|
+ .encoder(in.readOptionalString())
|
|
|
+ .useExplicitFieldOrder(in.readBoolean());
|
|
|
+ int fields = in.readVInt();
|
|
|
+ for (int i = 0; i < fields; i++) {
|
|
|
+ highlightBuilder.field(Field.PROTOTYPE.readFrom(in));
|
|
|
+ }
|
|
|
+ return highlightBuilder;
|
|
|
+ }
|
|
|
|
|
|
- public Field requireFieldMatch(boolean requireFieldMatch) {
|
|
|
- this.requireFieldMatch = requireFieldMatch;
|
|
|
- return this;
|
|
|
+ @Override
|
|
|
+ public void writeTo(StreamOutput out) throws IOException {
|
|
|
+ writeOptionsTo(out);
|
|
|
+ out.writeOptionalString(encoder);
|
|
|
+ out.writeBoolean(useExplicitFieldOrder);
|
|
|
+ out.writeVInt(fields.size());
|
|
|
+ for (int i = 0; i < fields.size(); i++) {
|
|
|
+ fields.get(i).writeTo(out);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- public Field boundaryMaxScan(int boundaryMaxScan) {
|
|
|
- this.boundaryMaxScan = boundaryMaxScan;
|
|
|
- return this;
|
|
|
- }
|
|
|
+ public static class Field extends AbstractHighlighterBuilder<Field> implements Writeable<Field> {
|
|
|
+ static final Field PROTOTYPE = new Field("_na_");
|
|
|
|
|
|
- public Field boundaryChars(char[] boundaryChars) {
|
|
|
- this.boundaryChars = boundaryChars;
|
|
|
- return this;
|
|
|
- }
|
|
|
+ private final String name;
|
|
|
|
|
|
- /**
|
|
|
- * Set type of highlighter to use. Out of the box supported types
|
|
|
- * are <tt>plain</tt>, <tt>fvh</tt> and <tt>postings</tt>.
|
|
|
- * This overrides global settings set by {@link HighlightBuilder#highlighterType(String)}.
|
|
|
- */
|
|
|
- public Field highlighterType(String highlighterType) {
|
|
|
- this.highlighterType = highlighterType;
|
|
|
- return this;
|
|
|
- }
|
|
|
+ int fragmentOffset = -1;
|
|
|
|
|
|
- /**
|
|
|
- * 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;
|
|
|
- }
|
|
|
+ String[] matchedFields;
|
|
|
|
|
|
- /**
|
|
|
- * Sets a query to use for highlighting this field instead of the search query.
|
|
|
- */
|
|
|
- public Field highlightQuery(QueryBuilder highlightQuery) {
|
|
|
- this.highlightQuery = highlightQuery;
|
|
|
- return this;
|
|
|
+ public Field(String name) {
|
|
|
+ this.name = name;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 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;
|
|
|
+ public String name() {
|
|
|
+ return name;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Allows to set custom options for custom highlighters.
|
|
|
- * This overrides global settings set by {@link HighlightBuilder#options(Map)}.
|
|
|
- */
|
|
|
- public Field options(Map<String, Object> options) {
|
|
|
- this.options = options;
|
|
|
+ public Field fragmentOffset(int fragmentOffset) {
|
|
|
+ this.fragmentOffset = fragmentOffset;
|
|
|
return this;
|
|
|
}
|
|
|
|
|
@@ -625,24 +280,47 @@ public class HighlightBuilder implements ToXContent {
|
|
|
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;
|
|
|
+ public void innerXContent(XContentBuilder builder) throws IOException {
|
|
|
+ builder.startObject(name);
|
|
|
+ // write common options
|
|
|
+ commonOptionsToXContent(builder);
|
|
|
+ // write special field-highlighter options
|
|
|
+ if (fragmentOffset != -1) {
|
|
|
+ builder.field("fragment_offset", fragmentOffset);
|
|
|
+ }
|
|
|
+ if (matchedFields != null) {
|
|
|
+ builder.field("matched_fields", matchedFields);
|
|
|
+ }
|
|
|
+ builder.endObject();
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ protected int doHashCode() {
|
|
|
+ return Objects.hash(name, fragmentOffset, Arrays.hashCode(matchedFields));
|
|
|
+ }
|
|
|
|
|
|
- /**
|
|
|
- * 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;
|
|
|
+ @Override
|
|
|
+ protected boolean doEquals(Field other) {
|
|
|
+ return Objects.equals(name, other.name) &&
|
|
|
+ Objects.equals(fragmentOffset, other.fragmentOffset) &&
|
|
|
+ Arrays.equals(matchedFields, other.matchedFields);
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public Field readFrom(StreamInput in) throws IOException {
|
|
|
+ Field field = new Field(in.readString());
|
|
|
+ field.fragmentOffset(in.readVInt());
|
|
|
+ field.matchedFields(in.readOptionalStringArray());
|
|
|
+ field.readOptionsFrom(in);
|
|
|
+ return field;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void writeTo(StreamOutput out) throws IOException {
|
|
|
+ out.writeString(name);
|
|
|
+ out.writeVInt(fragmentOffset);
|
|
|
+ out.writeOptionalStringArray(matchedFields);
|
|
|
+ writeOptionsTo(out);
|
|
|
+ }
|
|
|
}
|
|
|
}
|