Skip to content

Commit a002b40

Browse files
committed
Add support for condition token filter (#3523)
* Add support for condition token filter elastic/elasticseach#31958 * fix failing unit tests * fix failing unit tests
1 parent 6df0e29 commit a002b40

File tree

4 files changed

+105
-3
lines changed

4 files changed

+105
-3
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using Newtonsoft.Json;
4+
5+
namespace Nest
6+
{
7+
/// <summary>
8+
/// The conditional token filter takes a predicate script and a list of subfilters, and
9+
/// only applies the subfilters to the current token if it matches the predicate.
10+
/// </summary>
11+
public interface IConditionTokenFilter : ITokenFilter
12+
{
13+
/// <summary>
14+
/// a predicate script that determines whether or not the filters will be applied
15+
/// to the current token. Note that only inline scripts are supported
16+
/// </summary>
17+
[JsonProperty("script")]
18+
IScript Script { get; set; }
19+
20+
/// <summary>
21+
///a chain of token filters to apply to the current token if the predicate
22+
/// matches. These can be any token filters defined elsewhere in the index mappings.
23+
/// </summary>
24+
[JsonProperty("filter")]
25+
IEnumerable<string> Filters { get; set; }
26+
}
27+
28+
/// <inheritdoc cref="IConditionTokenFilter" />
29+
public class ConditionTokenFilter : TokenFilterBase, IConditionTokenFilter
30+
{
31+
public ConditionTokenFilter() : base("condition") { }
32+
33+
/// <inheritdoc cref="IConditionTokenFilter.Script" />
34+
public IScript Script { get; set; }
35+
36+
/// <inheritdoc cref="IConditionTokenFilter.Filters" />
37+
public IEnumerable<string> Filters { get; set; }
38+
}
39+
40+
/// <inheritdoc cref="IConditionTokenFilter" />
41+
public class ConditionTokenFilterDescriptor
42+
: TokenFilterDescriptorBase<ConditionTokenFilterDescriptor, IConditionTokenFilter>, IConditionTokenFilter
43+
{
44+
protected override string Type => "condition";
45+
46+
IScript IConditionTokenFilter.Script { get; set; }
47+
IEnumerable<string> IConditionTokenFilter.Filters { get; set; }
48+
49+
/// <inheritdoc cref="IConditionTokenFilter.Script" />
50+
public ConditionTokenFilterDescriptor Script(Func<ScriptDescriptor, IScript> scriptSelector) =>
51+
Assign(a => a.Script = scriptSelector?.Invoke(new ScriptDescriptor()));
52+
53+
/// <inheritdoc cref="IConditionTokenFilter.Script" />
54+
public ConditionTokenFilterDescriptor Script(string predicate) =>
55+
Assign(a => a.Script = new InlineScript(predicate));
56+
57+
/// <inheritdoc cref="IConditionTokenFilter.Filters" />
58+
public ConditionTokenFilterDescriptor Filters(params string[] filters) =>
59+
Assign(a => a.Filters = filters);
60+
61+
/// <inheritdoc cref="IConditionTokenFilter.Filters" />
62+
public ConditionTokenFilterDescriptor Filters(IEnumerable<string> filters) =>
63+
Assign(a => a.Filters = filters);
64+
65+
}
66+
}

src/Nest/Analysis/TokenFilters/TokenFilters.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@ public TokenFiltersDescriptor Standard(string name, Func<StandardTokenFilterDesc
225225
public TokenFiltersDescriptor Stemmer(string name, Func<StemmerTokenFilterDescriptor, IStemmerTokenFilter> selector) =>
226226
Assign(name, selector?.Invoke(new StemmerTokenFilterDescriptor()));
227227

228+
/// <inheritdoc cref="IConditionTokenFilter" />
229+
public TokenFiltersDescriptor Condition(string name, Func<ConditionTokenFilterDescriptor, IConditionTokenFilter> selector) =>
230+
Assign(name, selector?.Invoke(new ConditionTokenFilterDescriptor()));
231+
228232
/// <summary>
229233
/// Overrides stemming algorithms, by applying a custom mapping, then protecting these terms from being modified by stemmers. Must be placed
230234
/// before any stemming filters.

src/Nest/Indices/Analyze/AnalyzeTokenFilters.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,10 @@ public AnalyzeTokenFiltersDescriptor Standard(Func<StandardTokenFilterDescriptor
241241
AssignIfNotNull(selector.InvokeOrDefault(new StandardTokenFilterDescriptor()));
242242
#pragma warning restore 618
243243

244+
/// <inheritdoc cref="IConditionTokenFilter" />
245+
public AnalyzeTokenFiltersDescriptor Condition(Func<ConditionTokenFilterDescriptor, IConditionTokenFilter> selector) =>
246+
AssignIfNotNull(selector?.Invoke(new ConditionTokenFilterDescriptor()));
247+
244248
/// <summary>
245249
/// A filter that stems words (similar to snowball, but with more options).
246250
/// </summary>

src/Tests/Tests/Analysis/TokenFilters/TokenFilterTests.cs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -896,8 +896,35 @@ public class NoriPartOfSpeechTests : TokenFilterAssertionBase<NoriPartOfSpeechTe
896896
public override string Name => "nori_pos";
897897
}
898898

899+
[SkipVersion("<6.5.0", "Introduced in 6.5.0")]
900+
public class ConditionTests : TokenFilterAssertionBase<ConditionTests>
901+
{
902+
private readonly string _predicate = "token.getTerm().length() < 5";
903+
904+
public override FuncTokenFilters Fluent => (n, tf) => tf
905+
.Condition(n, t => t
906+
.Filters("lowercase", "lowercase, porter_stem")
907+
.Script(_predicate)
908+
);
909+
910+
public override ITokenFilter Initializer => new ConditionTokenFilter
911+
{
912+
Filters = new[] { "lowercase", "lowercase, porter_stem" },
913+
Script = new InlineScript(_predicate)
914+
};
915+
916+
public override object Json => new
917+
{
918+
type = "condition",
919+
filter = new[] { "lowercase", "lowercase, porter_stem" },
920+
script = new { source = _predicate }
921+
};
922+
923+
public override string Name => "condition";
924+
}
925+
899926
[SkipVersion("<6.4.0", "Introduced in 6.4.0")]
900-
public class MultiplexerTests : TokenFilterAssertionBase<PhoneticTests>
927+
public class MultiplexerTests : TokenFilterAssertionBase<MultiplexerTests>
901928
{
902929
public override FuncTokenFilters Fluent => (n, tf) => tf
903930
.Multiplexer(n, t => t
@@ -913,6 +940,7 @@ public class MultiplexerTests : TokenFilterAssertionBase<PhoneticTests>
913940

914941
public override object Json => new
915942
{
943+
type = "multiplexer",
916944
filters = new[] { "lowercase", "lowercase, porter_stem" },
917945
preserve_original = true
918946
};
@@ -921,11 +949,11 @@ public class MultiplexerTests : TokenFilterAssertionBase<PhoneticTests>
921949
}
922950

923951
[SkipVersion("<6.4.0", "Introduced in 6.4.0")]
924-
public class RemoveDuplicatesTests : TokenFilterAssertionBase<PhoneticTests>
952+
public class RemoveDuplicatesTests : TokenFilterAssertionBase<RemoveDuplicatesTests>
925953
{
926954
public override FuncTokenFilters Fluent => (n, tf) => tf.RemoveDuplicates(n);
927955
public override ITokenFilter Initializer => new RemoveDuplicatesTokenFilter { };
928-
public override object Json => new { };
956+
public override object Json => new { type = "remove_duplicates" };
929957
public override string Name => "dupes";
930958
}
931959
}

0 commit comments

Comments
 (0)