diff --git a/src/Nest/Analysis/TokenFilters/MultiplexerTokenFilter.cs b/src/Nest/Analysis/TokenFilters/MultiplexerTokenFilter.cs
new file mode 100644
index 00000000000..9454b6ad78a
--- /dev/null
+++ b/src/Nest/Analysis/TokenFilters/MultiplexerTokenFilter.cs
@@ -0,0 +1,50 @@
+using System.Collections;
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace Nest
+{
+ ///
+ /// A token filter of type multiplexer will emit multiple tokens at the same position, each version of the token having
+ /// been run through a different filter. Identical output tokens at the same position will be removed.
+ ///
+ public interface IMultiplexerTokenFilter : ITokenFilter
+ {
+ [JsonProperty("filters")]
+ IEnumerable Filters { get; set; }
+
+ [JsonProperty("preserve_original")]
+ bool? PreserveOriginal { get; set; }
+ }
+ public class MultiplexerTokenFilter : TokenFilterBase, IMultiplexerTokenFilter
+ {
+ internal const string TokenType = "multiplexer";
+ public MultiplexerTokenFilter() : base(TokenType) { }
+
+ ///
+ public IEnumerable Filters { get; set; }
+
+ ///
+ public bool? PreserveOriginal { get; set; }
+
+ }
+ ///
+ public class MultiplexerTokenFilterDescriptor
+ : TokenFilterDescriptorBase, IMultiplexerTokenFilter
+ {
+ protected override string Type => MultiplexerTokenFilter.TokenType;
+
+ IEnumerable IMultiplexerTokenFilter.Filters { get; set; }
+ bool? IMultiplexerTokenFilter.PreserveOriginal { get; set; }
+
+ ///
+ public MultiplexerTokenFilterDescriptor Filters(IEnumerable filters) => Assign(a => a.Filters = filters);
+
+ ///
+ public MultiplexerTokenFilterDescriptor Filters(params string[] filters) => Assign(a => a.Filters = filters);
+
+ ///
+ public MultiplexerTokenFilterDescriptor PreserveOriginal(bool? preserve = true) => Assign(a => a.PreserveOriginal = preserve);
+ }
+
+}
diff --git a/src/Nest/Analysis/TokenFilters/TokenFilters.cs b/src/Nest/Analysis/TokenFilters/TokenFilters.cs
index d44f4989acb..2b9fac67c65 100644
--- a/src/Nest/Analysis/TokenFilters/TokenFilters.cs
+++ b/src/Nest/Analysis/TokenFilters/TokenFilters.cs
@@ -317,5 +317,12 @@ public TokenFiltersDescriptor() : base(new TokenFilters())
///
public TokenFiltersDescriptor IcuTransform(string name, Func selector) =>
Assign(name, selector.Invoke(new IcuTransformTokenFilterDescriptor()));
+
+ ///
+ /// A token filter of type multiplexer will emit multiple tokens at the same position, each version of the token
+ /// having been run through a different filter. Identical output tokens at the same position will be removed.
+ ///
+ public TokenFiltersDescriptor Multiplexer(string name, Func selector) =>
+ Assign(name, selector.Invoke(new MultiplexerTokenFilterDescriptor()));
}
}
diff --git a/src/Nest/Indices/Analyze/AnalyzeTokenFilters.cs b/src/Nest/Indices/Analyze/AnalyzeTokenFilters.cs
index 17b4fd93ff8..4c9ad908d84 100644
--- a/src/Nest/Indices/Analyze/AnalyzeTokenFilters.cs
+++ b/src/Nest/Indices/Analyze/AnalyzeTokenFilters.cs
@@ -323,6 +323,10 @@ public class AnalyzeTokenFiltersDescriptor : DescriptorPromiseBase
public AnalyzeTokenFiltersDescriptor IcuTransform(Func selector) =>
AssignIfNotNull(selector.Invoke(new IcuTransformTokenFilterDescriptor()));
+
+ ///
+ public AnalyzeTokenFiltersDescriptor Multiplexer(Func selector) =>
+ AssignIfNotNull(selector.Invoke(new MultiplexerTokenFilterDescriptor()));
}
}
diff --git a/src/Tests/Tests/Analysis/TokenFilters/TokenFilterTests.cs b/src/Tests/Tests/Analysis/TokenFilters/TokenFilterTests.cs
index 4c702cf10d1..b21fcdb4f8a 100644
--- a/src/Tests/Tests/Analysis/TokenFilters/TokenFilterTests.cs
+++ b/src/Tests/Tests/Analysis/TokenFilters/TokenFilterTests.cs
@@ -1,4 +1,5 @@
-using System;
+using System;
+using Elastic.Xunit.XunitPlumbing;
using Nest;
using Tests.Framework;
@@ -878,5 +879,28 @@ public class PhoneticTests : TokenFilterAssertionBase
};
}
+
+ [SkipVersion("<6.4.0", "Introduced in 6.4.0")]
+ public class MultiplexerTests : TokenFilterAssertionBase
+ {
+ public override string Name => "multiplexer";
+ public override object Json => new
+ {
+ filters = new[]{"lowercase", "lowercase, porter_stem"},
+ preserve_original = true
+ };
+
+ public override ITokenFilter Initializer => new MultiplexerTokenFilter
+ {
+ Filters = new[] {"lowercase", "lowercase, porter_stem"},
+ PreserveOriginal = true
+ };
+
+ public override FuncTokenFilters Fluent => (n, tf) => tf
+ .Multiplexer(n, t => t
+ .Filters("lowercase", "lowercase, porter_stem")
+ .PreserveOriginal()
+ );
+ }
}
}