/* 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);
}
}