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

org.opensearch.search.fetch.subphase.highlight.SearchHighlightContext Maven / Gradle / Ivy

There is a newer version: 2.18.0
Show newest version
/*
 * SPDX-License-Identifier: Apache-2.0
 *
 * The OpenSearch Contributors require contributions made to
 * this file be licensed under the Apache-2.0 license or a
 * compatible open source license.
 */

/*
 * 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.
 */

/*
 * Modifications Copyright OpenSearch Contributors. See
 * GitHub history for details.
 */

package org.opensearch.search.fetch.subphase.highlight;

import org.apache.lucene.search.Query;
import org.opensearch.common.annotation.PublicApi;
import org.opensearch.search.fetch.subphase.highlight.HighlightBuilder.BoundaryScannerType;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

/**
 * Search context used during highlighting phase
 *
 * @opensearch.api
 */
@PublicApi(since = "1.0.0")
public class SearchHighlightContext {

    private final Map fields;
    private final boolean globalForceSource;

    public SearchHighlightContext(Collection fields) {
        this(fields, false);
    }

    public SearchHighlightContext(Collection fields, boolean globalForceSource) {
        assert fields != null;
        this.fields = new LinkedHashMap<>(fields.size());
        for (Field field : fields) {
            this.fields.put(field.field, field);
        }
        this.globalForceSource = globalForceSource;
    }

    public Collection fields() {
        return fields.values();
    }

    public boolean forceSource(Field field) {
        if (globalForceSource) {
            return true;
        }

        Field _field = fields.get(field.field);
        return _field == null ? false : _field.fieldOptions.forceSource;
    }

    /**
     * Field for the search highlight context
     *
     * @opensearch.api
     */
    @PublicApi(since = "1.0.0")
    public static class Field {
        private final String field;
        private final FieldOptions fieldOptions;

        Field(String field, FieldOptions fieldOptions) {
            assert field != null;
            assert fieldOptions != null;
            this.field = field;
            this.fieldOptions = fieldOptions;
        }

        public String field() {
            return field;
        }

        public FieldOptions fieldOptions() {
            return fieldOptions;
        }
    }

    /**
     * Field options for the search highlight context
     *
     * @opensearch.api
     */
    @PublicApi(since = "1.0.0")
    public static class FieldOptions {

        // Field options that default to null or -1 are often set to their real default in HighlighterParseElement#parse
        private int fragmentCharSize = -1;

        private int numberOfFragments = -1;

        private int fragmentOffset = -1;

        private String encoder;

        private String[] preTags;

        private String[] postTags;

        private Boolean scoreOrdered;

        private Boolean highlightFilter;

        private Boolean requireFieldMatch;

        private String highlighterType;

        private Boolean forceSource;

        private String fragmenter;

        private BoundaryScannerType boundaryScannerType;

        private int boundaryMaxScan = -1;

        private Character[] boundaryChars = null;

        private Locale boundaryScannerLocale;

        private Query highlightQuery;

        private int noMatchSize = -1;

        private Set matchedFields;

        private Map options;

        private int phraseLimit = -1;

        private Integer maxAnalyzerOffset = null;

        public Integer maxAnalyzerOffset() {
            return maxAnalyzerOffset;
        }

        public int fragmentCharSize() {
            return fragmentCharSize;
        }

        public int numberOfFragments() {
            return numberOfFragments;
        }

        public int fragmentOffset() {
            return fragmentOffset;
        }

        public String encoder() {
            return encoder;
        }

        public String[] preTags() {
            return preTags;
        }

        public String[] postTags() {
            return postTags;
        }

        public Boolean scoreOrdered() {
            return scoreOrdered;
        }

        public Boolean highlightFilter() {
            return highlightFilter;
        }

        public Boolean requireFieldMatch() {
            return requireFieldMatch;
        }

        public String highlighterType() {
            return highlighterType;
        }

        public String fragmenter() {
            return fragmenter;
        }

        public BoundaryScannerType boundaryScannerType() {
            return boundaryScannerType;
        }

        public int boundaryMaxScan() {
            return boundaryMaxScan;
        }

        public Character[] boundaryChars() {
            return boundaryChars;
        }

        public Locale boundaryScannerLocale() {
            return boundaryScannerLocale;
        }

        public Query highlightQuery() {
            return highlightQuery;
        }

        public int noMatchSize() {
            return noMatchSize;
        }

        public int phraseLimit() {
            return phraseLimit;
        }

        public Set matchedFields() {
            return matchedFields;
        }

        public Map options() {
            return options;
        }

        static class Builder {

            private final FieldOptions fieldOptions = new FieldOptions();

            Builder fragmentCharSize(int fragmentCharSize) {
                fieldOptions.fragmentCharSize = fragmentCharSize;
                return this;
            }

            Builder numberOfFragments(int numberOfFragments) {
                fieldOptions.numberOfFragments = numberOfFragments;
                return this;
            }

            Builder fragmentOffset(int fragmentOffset) {
                fieldOptions.fragmentOffset = fragmentOffset;
                return this;
            }

            Builder encoder(String encoder) {
                fieldOptions.encoder = encoder;
                return this;
            }

            Builder preTags(String[] preTags) {
                fieldOptions.preTags = preTags;
                return this;
            }

            Builder postTags(String[] postTags) {
                fieldOptions.postTags = postTags;
                return this;
            }

            Builder scoreOrdered(boolean scoreOrdered) {
                fieldOptions.scoreOrdered = scoreOrdered;
                return this;
            }

            Builder highlightFilter(boolean highlightFilter) {
                fieldOptions.highlightFilter = highlightFilter;
                return this;
            }

            Builder requireFieldMatch(boolean requireFieldMatch) {
                fieldOptions.requireFieldMatch = requireFieldMatch;
                return this;
            }

            Builder highlighterType(String type) {
                fieldOptions.highlighterType = type;
                return this;
            }

            Builder forceSource(boolean forceSource) {
                fieldOptions.forceSource = forceSource;
                return this;
            }

            Builder fragmenter(String fragmenter) {
                fieldOptions.fragmenter = fragmenter;
                return this;
            }

            Builder boundaryScannerType(BoundaryScannerType boundaryScanner) {
                fieldOptions.boundaryScannerType = boundaryScanner;
                return this;
            }

            Builder boundaryMaxScan(int boundaryMaxScan) {
                fieldOptions.boundaryMaxScan = boundaryMaxScan;
                return this;
            }

            Builder boundaryChars(Character[] boundaryChars) {
                fieldOptions.boundaryChars = boundaryChars;
                return this;
            }

            Builder boundaryScannerLocale(Locale boundaryScannerLocale) {
                fieldOptions.boundaryScannerLocale = boundaryScannerLocale;
                return this;
            }

            Builder highlightQuery(Query highlightQuery) {
                fieldOptions.highlightQuery = highlightQuery;
                return this;
            }

            Builder noMatchSize(int noMatchSize) {
                fieldOptions.noMatchSize = noMatchSize;
                return this;
            }

            Builder phraseLimit(int phraseLimit) {
                fieldOptions.phraseLimit = phraseLimit;
                return this;
            }

            Builder maxAnalyzerOffset(Integer maxAnalyzerOffset) {
                // throws an execption if the value is not a positive integer
                if (maxAnalyzerOffset != null && maxAnalyzerOffset <= 0) {
                    throw new IllegalArgumentException("the value [" + maxAnalyzerOffset + "] of max_analyzer_offset is invalid");
                }
                fieldOptions.maxAnalyzerOffset = maxAnalyzerOffset;
                return this;
            }

            Builder matchedFields(Set matchedFields) {
                fieldOptions.matchedFields = matchedFields;
                return this;
            }

            Builder options(Map options) {
                fieldOptions.options = options;
                return this;
            }

            FieldOptions build() {
                return fieldOptions;
            }

            Builder merge(FieldOptions globalOptions) {
                if (fieldOptions.preTags == null && globalOptions.preTags != null) {
                    fieldOptions.preTags = Arrays.copyOf(globalOptions.preTags, globalOptions.preTags.length);
                }
                if (fieldOptions.postTags == null && globalOptions.postTags != null) {
                    fieldOptions.postTags = Arrays.copyOf(globalOptions.postTags, globalOptions.postTags.length);
                }
                if (fieldOptions.highlightFilter == null) {
                    fieldOptions.highlightFilter = globalOptions.highlightFilter;
                }
                if (fieldOptions.scoreOrdered == null) {
                    fieldOptions.scoreOrdered = globalOptions.scoreOrdered;
                }
                if (fieldOptions.fragmentCharSize == -1) {
                    fieldOptions.fragmentCharSize = globalOptions.fragmentCharSize;
                }
                if (fieldOptions.numberOfFragments == -1) {
                    fieldOptions.numberOfFragments = globalOptions.numberOfFragments;
                }
                if (fieldOptions.encoder == null) {
                    fieldOptions.encoder = globalOptions.encoder;
                }
                if (fieldOptions.requireFieldMatch == null) {
                    fieldOptions.requireFieldMatch = globalOptions.requireFieldMatch;
                }
                if (fieldOptions.boundaryScannerType == null) {
                    fieldOptions.boundaryScannerType = globalOptions.boundaryScannerType;
                }
                if (fieldOptions.boundaryMaxScan == -1) {
                    fieldOptions.boundaryMaxScan = globalOptions.boundaryMaxScan;
                }
                if (fieldOptions.boundaryChars == null && globalOptions.boundaryChars != null) {
                    fieldOptions.boundaryChars = Arrays.copyOf(globalOptions.boundaryChars, globalOptions.boundaryChars.length);
                }
                if (fieldOptions.boundaryScannerLocale == null) {
                    fieldOptions.boundaryScannerLocale = globalOptions.boundaryScannerLocale;
                }
                if (fieldOptions.highlighterType == null) {
                    fieldOptions.highlighterType = globalOptions.highlighterType;
                }
                if (fieldOptions.fragmenter == null) {
                    fieldOptions.fragmenter = globalOptions.fragmenter;
                }
                if ((fieldOptions.options == null || fieldOptions.options.size() == 0) && globalOptions.options != null) {
                    fieldOptions.options = new HashMap<>(globalOptions.options);
                }
                if (fieldOptions.highlightQuery == null && globalOptions.highlightQuery != null) {
                    fieldOptions.highlightQuery = globalOptions.highlightQuery;
                }
                if (fieldOptions.noMatchSize == -1) {
                    fieldOptions.noMatchSize = globalOptions.noMatchSize;
                }
                if (fieldOptions.forceSource == null) {
                    fieldOptions.forceSource = globalOptions.forceSource;
                }
                if (fieldOptions.phraseLimit == -1) {
                    fieldOptions.phraseLimit = globalOptions.phraseLimit;
                }
                if (fieldOptions.maxAnalyzerOffset == null) {
                    fieldOptions.maxAnalyzerOffset = globalOptions.maxAnalyzerOffset;
                }
                return this;
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy