/* 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. */ /* * Modifications Copyright OpenSearch Contributors. See * GitHub history for details. * * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch B.V. 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. */ using System; using System.Runtime.Serialization; using OpenSearch.Net.Utf8Json; namespace OpenSearch.Client { /// /// A match query across multiple fields. /// [InterfaceDataContract] [ReadAs(typeof(MultiMatchQuery))] public interface IMultiMatchQuery : IQuery { /// /// The analyzer name used to analyze the query /// [DataMember(Name = "analyzer")] string Analyzer { get; set; } /// [DataMember(Name = "auto_generate_synonyms_phrase_query")] bool? AutoGenerateSynonymsPhraseQuery { get; set; } /// /// A cutoff frequency that allows specifying an absolute or relative document frequency where /// high frequency terms are moved into an optional subquery and are only scored if one of the low frequency /// (below the cutoff) terms in the case of , /// or all of the low frequency terms in the case of an match. /// [DataMember(Name = "cutoff_frequency")] double? CutoffFrequency { get; set; } /// /// The fields to perform the query against. /// [DataMember(Name = "fields")] Fields Fields { get; set; } /// /// Allows fuzzy matching based on the type of field being queried. /// Cannot be used with the /// , /// or /// types. /// [DataMember(Name = "fuzziness")] Fuzziness Fuzziness { get; set; } /// /// Controls how the query is rewritten if is set. /// In this scenario, the default is . /// [DataMember(Name = "fuzzy_rewrite")] MultiTermQueryRewrite FuzzyRewrite { get; set; } /// /// Sets whether transpositions are supported in fuzzy queries. /// /// The default metric used by fuzzy queries to determine a match is the Damerau-Levenshtein /// distance formula which supports transpositions. Setting transposition to false will /// switch to classic Levenshtein distance. /// If not set, Damerau-Levenshtein distance metric will be used. /// [DataMember(Name = "fuzzy_transpositions")] bool? FuzzyTranspositions { get; set; } /// /// If set to true will cause format based failures (like providing text to a numeric field) /// to be ignored /// [DataMember(Name = "lenient")] bool? Lenient { get; set; } /// /// Controls the number of terms fuzzy queries will expand to. Defaults to 50 /// [DataMember(Name = "max_expansions")] int? MaxExpansions { get; set; } /// /// A value controlling how many "should" clauses in the resulting boolean query should match. /// It can be an absolute value, a percentage or a combination of both. /// [DataMember(Name = "minimum_should_match")] MinimumShouldMatch MinimumShouldMatch { get; set; } /// /// The operator used if no explicit operator is specified. /// The default operator is /// /// /// and types are field-centric ; /// they generate a match query per field. This means that and /// are applied to each field individually, which is probably not what you want. /// Consider using . /// [DataMember(Name = "operator")] Operator? Operator { get; set; } /// /// Set the prefix length for fuzzy queries. Default is 0. /// [DataMember(Name = "prefix_length")] int? PrefixLength { get; set; } /// /// The query to execute /// [DataMember(Name = "query")] string Query { get; set; } /// /// How far apart terms are allowed to be while still considering the document to be a match. /// [DataMember(Name = "slop")] int? Slop { get; set; } /// /// Used to influence how the score is calculated for . If specified, /// score is calculated using /// [DataMember(Name = "tie_breaker")] double? TieBreaker { get; set; } /// /// How the fields should be combined to build the text query. /// Default is /// [DataMember(Name = "type")] TextQueryType? Type { get; set; } /// /// By default, a generates a match clause per field, then wraps them /// in a . By setting to false, /// they will be wrapped in a instead. /// [DataMember(Name = "use_dis_max")] bool? UseDisMax { get; set; } /// /// If the analyzer used removes all tokens in a query like a stop filter does, the default behavior is /// to match no documents at all. In order to change that, can be used, /// which accepts (default) and /// which corresponds to a match_all query. /// [DataMember(Name = "zero_terms_query")] ZeroTermsQuery? ZeroTermsQuery { get; set; } } /// public class MultiMatchQuery : QueryBase, IMultiMatchQuery { /// public string Analyzer { get; set; } /// public bool? AutoGenerateSynonymsPhraseQuery { get; set; } /// public double? CutoffFrequency { get; set; } /// public Fields Fields { get; set; } /// public Fuzziness Fuzziness { get; set; } /// public MultiTermQueryRewrite FuzzyRewrite { get; set; } /// public bool? FuzzyTranspositions { get; set; } /// public bool? Lenient { get; set; } /// public int? MaxExpansions { get; set; } /// public MinimumShouldMatch MinimumShouldMatch { get; set; } /// public Operator? Operator { get; set; } /// public int? PrefixLength { get; set; } /// public string Query { get; set; } /// public int? Slop { get; set; } /// public double? TieBreaker { get; set; } /// public TextQueryType? Type { get; set; } /// public bool? UseDisMax { get; set; } /// public ZeroTermsQuery? ZeroTermsQuery { get; set; } protected override bool Conditionless => IsConditionless(this); internal override void InternalWrapInContainer(IQueryContainer c) => c.MultiMatch = this; internal static bool IsConditionless(IMultiMatchQuery q) => q.Query.IsNullOrEmpty(); } /// [DataContract] public class MultiMatchQueryDescriptor : QueryDescriptorBase, IMultiMatchQuery> , IMultiMatchQuery where T : class { protected override bool Conditionless => MultiMatchQuery.IsConditionless(this); string IMultiMatchQuery.Analyzer { get; set; } bool? IMultiMatchQuery.AutoGenerateSynonymsPhraseQuery { get; set; } double? IMultiMatchQuery.CutoffFrequency { get; set; } Fields IMultiMatchQuery.Fields { get; set; } Fuzziness IMultiMatchQuery.Fuzziness { get; set; } MultiTermQueryRewrite IMultiMatchQuery.FuzzyRewrite { get; set; } bool? IMultiMatchQuery.FuzzyTranspositions { get; set; } bool? IMultiMatchQuery.Lenient { get; set; } int? IMultiMatchQuery.MaxExpansions { get; set; } MinimumShouldMatch IMultiMatchQuery.MinimumShouldMatch { get; set; } Operator? IMultiMatchQuery.Operator { get; set; } int? IMultiMatchQuery.PrefixLength { get; set; } string IMultiMatchQuery.Query { get; set; } int? IMultiMatchQuery.Slop { get; set; } double? IMultiMatchQuery.TieBreaker { get; set; } TextQueryType? IMultiMatchQuery.Type { get; set; } bool? IMultiMatchQuery.UseDisMax { get; set; } ZeroTermsQuery? IMultiMatchQuery.ZeroTermsQuery { get; set; } /// public MultiMatchQueryDescriptor Fields(Func, IPromise> fields) => Assign(fields, (a, v) => a.Fields = v?.Invoke(new FieldsDescriptor())?.Value); /// public MultiMatchQueryDescriptor Fields(Fields fields) => Assign(fields, (a, v) => a.Fields = v); /// public MultiMatchQueryDescriptor Query(string query) => Assign(query, (a, v) => a.Query = v); /// public MultiMatchQueryDescriptor Analyzer(string analyzer) => Assign(analyzer, (a, v) => a.Analyzer = v); /// public MultiMatchQueryDescriptor Fuzziness(Fuzziness fuzziness) => Assign(fuzziness, (a, v) => a.Fuzziness = v); /// public MultiMatchQueryDescriptor CutoffFrequency(double? cutoffFrequency) => Assign(cutoffFrequency, (a, v) => a.CutoffFrequency = v); /// public MultiMatchQueryDescriptor MinimumShouldMatch(MinimumShouldMatch minimumShouldMatch) => Assign(minimumShouldMatch, (a, v) => a.MinimumShouldMatch = v); /// public MultiMatchQueryDescriptor FuzzyRewrite(MultiTermQueryRewrite rewrite) => Assign(rewrite, (a, v) => a.FuzzyRewrite = v); /// public MultiMatchQueryDescriptor FuzzyTranspositions(bool? fuzzyTranpositions = true) => Assign(fuzzyTranpositions, (a, v) => a.FuzzyTranspositions = v); /// public MultiMatchQueryDescriptor Lenient(bool? lenient = true) => Assign(lenient, (a, v) => a.Lenient = v); /// public MultiMatchQueryDescriptor PrefixLength(int? prefixLength) => Assign(prefixLength, (a, v) => a.PrefixLength = v); /// public MultiMatchQueryDescriptor MaxExpansions(int? maxExpansions) => Assign(maxExpansions, (a, v) => a.MaxExpansions = v); /// public MultiMatchQueryDescriptor Slop(int? slop) => Assign(slop, (a, v) => a.Slop = v); /// public MultiMatchQueryDescriptor Operator(Operator? op) => Assign(op, (a, v) => a.Operator = v); /// public MultiMatchQueryDescriptor TieBreaker(double? tieBreaker) => Assign(tieBreaker, (a, v) => a.TieBreaker = v); /// public MultiMatchQueryDescriptor Type(TextQueryType? type) => Assign(type, (a, v) => a.Type = v); /// public MultiMatchQueryDescriptor UseDisMax(bool? useDisMax = true) => Assign(useDisMax, (a, v) => a.UseDisMax = v); /// public MultiMatchQueryDescriptor ZeroTermsQuery(ZeroTermsQuery? zeroTermsQuery) => Assign(zeroTermsQuery, (a, v) => a.ZeroTermsQuery = v); /// public MultiMatchQueryDescriptor AutoGenerateSynonymsPhraseQuery(bool? autoGenerateSynonymsPhraseQuery = true) => Assign(autoGenerateSynonymsPhraseQuery, (a, v) => a.AutoGenerateSynonymsPhraseQuery = v); } }