diff --git a/src/Nest/QueryDsl/FullText/Intervals/IntervalsFuzzy.cs b/src/Nest/QueryDsl/FullText/Intervals/IntervalsFuzzy.cs
new file mode 100644
index 00000000000..a9da1ccbc90
--- /dev/null
+++ b/src/Nest/QueryDsl/FullText/Intervals/IntervalsFuzzy.cs
@@ -0,0 +1,107 @@
+using System;
+using System.Linq.Expressions;
+using System.Runtime.Serialization;
+
+namespace Nest
+{
+ ///
+ /// The fuzzy rule matches terms that are similar to the provided term, within an edit distance defined by Fuzziness.
+ /// If the fuzzy expansion matches more than 128 terms, Elasticsearch returns an error.
+ ///
+ /// Available in Elasticsearch 7.6.0+
+ ///
+ [ReadAs(typeof(IntervalsFuzzy))]
+ public interface IIntervalsFuzzy : IIntervalsNoFilter
+ {
+ ///
+ /// Analyzer used to normalize the term. Defaults to the top-level field's analyzer.
+ ///
+ [DataMember(Name = "analyzer")]
+ string Analyzer { get; set; }
+
+ ///
+ /// Number of beginning characters left unchanged when creating expansions. Defaults to 0.
+ ///
+ [DataMember(Name = "prefix_length")]
+ int? PrefixLength { get; set; }
+
+ ///
+ /// Indicates whether edits include transpositions of two adjacent characters (ab → ba). Defaults to true.
+ ///
+ [DataMember(Name = "transpositions")]
+ bool? Transpositions { get; set; }
+
+ ///
+ /// Maximum edit distance allowed for matching. See Fuzziness for valid values and more information.
+ /// Defaults to .
+ ///
+ [DataMember(Name = "fuzziness")]
+ Fuzziness Fuzziness { get; set; }
+
+ ///
+ /// The term to match.
+ ///
+ [DataMember(Name = "term")]
+ string Term { get; set; }
+
+ ///
+ /// If specified, then match intervals from this field rather than the top-level field.
+ /// The term is normalized using the search analyzer from this field,
+ /// unless analyzer is specified separately.
+ ///
+ [DataMember(Name = "use_field")]
+ Field UseField { get; set; }
+ }
+
+ ///
+ public class IntervalsFuzzy : IntervalsNoFilterBase, IIntervalsFuzzy
+ {
+ internal override void WrapInContainer(IIntervalsContainer container) => container.Fuzzy = this;
+
+ ///
+ public string Analyzer { get; set; }
+ ///
+ public int? PrefixLength { get; set; }
+ ///
+ public bool? Transpositions { get; set; }
+ ///
+ public Fuzziness Fuzziness { get; set; }
+ ///
+ public string Term { get; set; }
+ ///
+ public Field UseField { get; set; }
+ }
+
+ ///
+ public class IntervalsFuzzyDescriptor : DescriptorBase, IIntervalsFuzzy
+ {
+ string IIntervalsFuzzy.Analyzer { get; set; }
+ int? IIntervalsFuzzy.PrefixLength { get; set; }
+ bool? IIntervalsFuzzy.Transpositions { get; set; }
+ Fuzziness IIntervalsFuzzy.Fuzziness { get; set; }
+ string IIntervalsFuzzy.Term { get; set; }
+ Field IIntervalsFuzzy.UseField { get; set; }
+
+ ///
+ public IntervalsFuzzyDescriptor Analyzer(string analyzer) => Assign(analyzer, (a, v) => a.Analyzer = v);
+
+ ///
+ public IntervalsFuzzyDescriptor PrefixLength(int? prefixLength) => Assign(prefixLength, (a, v) => a.PrefixLength = v);
+
+ ///
+ public IntervalsFuzzyDescriptor Transpositions(bool? transpositions = true) => Assign(transpositions, (a, v) => a.Transpositions = v);
+
+ ///
+ public IntervalsFuzzyDescriptor Fuzziness(Fuzziness fuzziness) => Assign(fuzziness, (a, v) => a.Fuzziness = v);
+
+ ///
+ public IntervalsFuzzyDescriptor Term(string term) => Assign(term, (a, v) => a.Term = v);
+
+
+ ///
+ public IntervalsFuzzyDescriptor UseField(Expression> objectPath) => Assign(objectPath, (a, v) => a.UseField = v);
+
+ ///
+ public IntervalsFuzzyDescriptor UseField(Field useField) => Assign(useField, (a, v) => a.UseField = v);
+ }
+}
diff --git a/src/Nest/QueryDsl/FullText/Intervals/IntervalsQuery.cs b/src/Nest/QueryDsl/FullText/Intervals/IntervalsQuery.cs
index 30cb8f92abb..39c87227493 100644
--- a/src/Nest/QueryDsl/FullText/Intervals/IntervalsQuery.cs
+++ b/src/Nest/QueryDsl/FullText/Intervals/IntervalsQuery.cs
@@ -25,6 +25,8 @@ public class IntervalsQuery : FieldNameQueryBase, IIntervalsQuery
public IIntervalsAnyOf AnyOf { get; set; }
///
public IIntervalsMatch Match { get; set; }
+ ///
+ public IIntervalsFuzzy Fuzzy { get; set; }
///
public IIntervalsPrefix Prefix { get; set; }
@@ -35,7 +37,8 @@ public class IntervalsQuery : FieldNameQueryBase, IIntervalsQuery
protected override bool Conditionless => IsConditionless(this);
internal static bool IsConditionless(IIntervalsQuery q) =>
- q.Field.IsConditionless() || q.Match == null && q.AllOf == null && q.AnyOf == null && q.Prefix == null && q.Wildcard == null;
+ q.Field.IsConditionless() || q.Match == null && q.AllOf == null && q.AnyOf == null && q.Prefix == null && q.Wildcard == null
+ && q.Fuzzy == null;
internal override void InternalWrapInContainer(IQueryContainer container) => container.Intervals = this;
}
@@ -50,10 +53,15 @@ public class IntervalsQueryDescriptor
IIntervalsAllOf IIntervalsContainer.AllOf { get; set; }
IIntervalsAnyOf IIntervalsContainer.AnyOf { get; set; }
+ IIntervalsFuzzy IIntervalsContainer.Fuzzy { get; set; }
IIntervalsMatch IIntervalsContainer.Match { get; set; }
IIntervalsPrefix IIntervalsContainer.Prefix { get; set; }
IIntervalsWildcard IIntervalsContainer.Wildcard { get; set; }
+ ///
+ public IntervalsQueryDescriptor Fuzzy(Func selector) =>
+ Assign(selector, (a, v) => a.Fuzzy = v?.Invoke(new IntervalsFuzzyDescriptor()));
+
///
public IntervalsQueryDescriptor Match(Func selector) =>
Assign(selector, (a, v) => a.Match = v?.Invoke(new IntervalsMatchDescriptor()));
@@ -88,6 +96,10 @@ public interface IIntervalsContainer
[DataMember(Name = "any_of")]
IIntervalsAnyOf AnyOf { get; set; }
+ ///
+ [DataMember(Name = "fuzzy")]
+ IIntervalsFuzzy Fuzzy { get; set; }
+
///
[DataMember(Name = "match")]
IIntervalsMatch Match { get; set; }
@@ -120,6 +132,7 @@ public IntervalsContainer(IntervalsNoFilterBase intervals)
IIntervalsAllOf IIntervalsContainer.AllOf { get; set; }
IIntervalsAnyOf IIntervalsContainer.AnyOf { get; set; }
+ IIntervalsFuzzy IIntervalsContainer.Fuzzy { get; set; }
IIntervalsMatch IIntervalsContainer.Match { get; set; }
IIntervalsPrefix IIntervalsContainer.Prefix { get; set; }
IIntervalsWildcard IIntervalsContainer.Wildcard { get; set; }
@@ -141,6 +154,10 @@ public class IntervalsDescriptor : IntervalsContainer
private IntervalsDescriptor Assign(TValue value, Action assigner) =>
Fluent.Assign(this, value, assigner);
+ ///
+ public IntervalsDescriptor Fuzzy(Func selector) =>
+ Assign(selector, (a, v) => a.Fuzzy = v?.Invoke(new IntervalsFuzzyDescriptor()));
+
///
public IntervalsDescriptor Match(Func selector) =>
Assign(selector, (a, v) => a.Match = v?.Invoke(new IntervalsMatchDescriptor()));
@@ -222,6 +239,10 @@ public class IntervalsListDescriptor : DescriptorPromiseBase()) { }
+ ///
+ public IntervalsListDescriptor Fuzzy(Func selector) =>
+ Assign(selector, (a, v) => a.AddIfNotNull(new IntervalsDescriptor().Fuzzy(v)));
+
///
public IntervalsListDescriptor Match(Func selector) =>
Assign(selector, (a, v) => a.AddIfNotNull(new IntervalsDescriptor().Match(v)));
diff --git a/tests/Tests/QueryDsl/FullText/Intervals/IntervalsUsageTests.cs b/tests/Tests/QueryDsl/FullText/Intervals/IntervalsUsageTests.cs
index 9d71d8fef24..26c7c0b7dc7 100644
--- a/tests/Tests/QueryDsl/FullText/Intervals/IntervalsUsageTests.cs
+++ b/tests/Tests/QueryDsl/FullText/Intervals/IntervalsUsageTests.cs
@@ -262,4 +262,62 @@ protected override QueryContainer QueryFluent(QueryContainerDescriptor
)
);
}
+
+ /**[float]
+ * === Fuzzy rules
+ *
+ * Fuzzy rules can be used to match terms that are similar to the provided term, within an edit distance defined by Fuzziness.
+ * If the fuzzy expansion matches more than 128 terms, Elasticsearch returns an error.
+ *
+ * NOTE: Only available in Elasticsearch 7.6.0+
+ */
+ [SkipVersion("<7.6.0", "fuzzy rules introduced in 7.6.0")]
+ public class IntervalsFuzzyUsageTests : QueryDslUsageTestsBase
+ {
+ public IntervalsFuzzyUsageTests(ReadOnlyCluster i, EndpointUsage usage) : base(i, usage) { }
+
+ private static readonly string IntervalsPrefix = Project.First.Description.Split(' ')[0];
+
+ private static readonly string IntervalsFuzzy = IntervalsPrefix.Substring(0, IntervalsPrefix.Length) + "z";
+
+ protected override QueryContainer QueryInitializer => new IntervalsQuery
+ {
+ Field = Field(p => p.Description),
+ Name = "named_query",
+ Boost = 1.1,
+ Fuzzy = new IntervalsFuzzy
+ {
+ Term = IntervalsFuzzy,
+ Fuzziness = Fuzziness.Auto
+ }
+ };
+
+ protected override object QueryJson => new
+ {
+ intervals = new
+ {
+ description = new
+ {
+ _name = "named_query",
+ boost = 1.1,
+ fuzzy = new
+ {
+ term = IntervalsFuzzy,
+ fuzziness = "AUTO"
+ }
+ }
+ }
+ };
+
+ protected override QueryContainer QueryFluent(QueryContainerDescriptor q) => q
+ .Intervals(c => c
+ .Field(p => p.Description)
+ .Name("named_query")
+ .Boost(1.1)
+ .Fuzzy(m => m
+ .Term(IntervalsFuzzy)
+ .Fuzziness(Fuzziness.Auto)
+ )
+ );
+ }
}