Skip to content

Commit afca8bc

Browse files
authored
Support case_insensitive on term-based queries (#5412)
* Support case_insensitive on term-based queries * Cleanup span query
1 parent d3f1060 commit afca8bc

File tree

5 files changed

+91
-5
lines changed

5 files changed

+91
-5
lines changed

src/Nest/QueryDsl/Span/Term/SpanTermQuery.cs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,33 @@ namespace Nest
99
{
1010
[InterfaceDataContract]
1111
[JsonFormatter(typeof(FieldNameQueryFormatter<SpanTermQuery, ISpanTermQuery>))]
12-
public interface ISpanTermQuery : ITermQuery, ISpanSubQuery { }
12+
public interface ISpanTermQuery : ISpanSubQuery, IFieldNameQuery
13+
{
14+
[DataMember(Name = "value")]
15+
[JsonFormatter(typeof(SourceWriteFormatter<object>))]
16+
object Value { get; set; }
17+
}
1318

1419
[DataContract]
1520
public class SpanTermQuery : FieldNameQueryBase, ISpanTermQuery
1621
{
1722
public object Value { get; set; }
18-
19-
protected override bool Conditionless => TermQuery.IsConditionless(this);
23+
24+
protected override bool Conditionless => IsConditionless(this);
2025

2126
internal override void InternalWrapInContainer(IQueryContainer c) => c.SpanTerm = this;
27+
28+
internal static bool IsConditionless(ISpanTermQuery q) => q.Value == null || q.Value.ToString().IsNullOrEmpty() || q.Field.IsConditionless();
2229
}
2330

24-
public class SpanTermQueryDescriptor<T> : TermQueryDescriptorBase<SpanTermQueryDescriptor<T>, ISpanTermQuery, T>, ISpanTermQuery
25-
where T : class { }
31+
public class SpanTermQueryDescriptor<T> : FieldNameQueryDescriptorBase<SpanTermQueryDescriptor<T>, ISpanTermQuery, T>, ISpanTermQuery
32+
where T : class
33+
{
34+
protected override bool Conditionless => SpanTermQuery.IsConditionless(this);
35+
36+
object ISpanTermQuery.Value { get; set; }
37+
38+
public SpanTermQueryDescriptor<T> Value(object value) =>
39+
Assign(value, (a, v) => a.Value = v);
40+
}
2641
}

src/Nest/QueryDsl/TermLevel/Prefix/PrefixQuery.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public class PrefixQuery : FieldNameQueryBase, IPrefixQuery
2020
{
2121
public MultiTermQueryRewrite Rewrite { get; set; }
2222
public object Value { get; set; }
23+
public bool? CaseInsensitive { get; set; }
2324
protected override bool Conditionless => TermQuery.IsConditionless(this);
2425

2526
internal override void InternalWrapInContainer(IQueryContainer c) => c.Prefix = this;

src/Nest/QueryDsl/TermLevel/Term/TermQuery.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,17 @@ public interface ITermQuery : IFieldNameQuery
1414
[DataMember(Name = "value")]
1515
[JsonFormatter(typeof(SourceWriteFormatter<object>))]
1616
object Value { get; set; }
17+
18+
[DataMember(Name = "case_insensitive")]
19+
bool? CaseInsensitive { get; set; }
1720
}
1821

1922
[DataContract]
2023
public class TermQuery : FieldNameQueryBase, ITermQuery
2124
{
2225
public object Value { get; set; }
26+
27+
public bool? CaseInsensitive { get; set; }
2328

2429
protected override bool Conditionless => IsConditionless(this);
2530

@@ -37,12 +42,19 @@ public abstract class TermQueryDescriptorBase<TDescriptor, TInterface, T>
3742
{
3843
protected override bool Conditionless => TermQuery.IsConditionless(this);
3944
object ITermQuery.Value { get; set; }
45+
bool? ITermQuery.CaseInsensitive { get; set; }
4046

4147
public TDescriptor Value(object value)
4248
{
4349
Self.Value = value;
4450
return (TDescriptor)this;
4551
}
52+
53+
public TDescriptor CaseInsensitive(bool? caseInsensitive = true)
54+
{
55+
Self.CaseInsensitive = caseInsensitive;
56+
return (TDescriptor)this;
57+
}
4658
}
4759

4860
public class TermQueryDescriptor<T> : TermQueryDescriptorBase<TermQueryDescriptor<T>, ITermQuery, T>

src/Nest/QueryDsl/TermLevel/Wildcard/WildcardQuery.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public class WildcardQuery : FieldNameQueryBase, IWildcardQuery
2727
{
2828
public MultiTermQueryRewrite Rewrite { get; set; }
2929
public object Value { get; set; }
30+
public bool? CaseInsensitive { get; set; }
3031
protected override bool Conditionless => TermQuery.IsConditionless(this);
3132

3233
internal override void InternalWrapInContainer(IQueryContainer c) => c.Wildcard = this;

tests/Tests/QueryDsl/TermLevel/Term/TermQueryUsageTests.cs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,61 @@ protected override QueryContainer QueryFluent(QueryContainerDescriptor<Project>
104104
.Value(string.Empty)
105105
);
106106
}
107+
108+
//hide
109+
[SkipVersion("<7.10.0", "Case insensitive flag added in 7.10.0")]
110+
public class TermQueryWithCaseInsensitiveUsageTests : QueryDslUsageTestsBase
111+
{
112+
public TermQueryWithCaseInsensitiveUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : base(cluster, usage) { }
113+
114+
protected override ConditionlessWhen ConditionlessWhen => new ConditionlessWhen<ITermQuery>(q => q.Term)
115+
{
116+
q => q.Field = null,
117+
q => q.Value = " ",
118+
q => q.Value = null
119+
};
120+
121+
protected override QueryContainer QueryInitializer => new TermQuery
122+
{
123+
Name = "named_query",
124+
Boost = 1.1,
125+
Field = "description",
126+
Value = "project description",
127+
CaseInsensitive = true
128+
};
129+
130+
protected override object QueryJson => new
131+
{
132+
term = new
133+
{
134+
description = new
135+
{
136+
_name = "named_query",
137+
boost = 1.1,
138+
value = "project description",
139+
case_insensitive = true
140+
}
141+
}
142+
};
143+
144+
protected override QueryContainer QueryFluent(QueryContainerDescriptor<Project> q) => q
145+
.Term(c => c
146+
.Name("named_query")
147+
.Boost(1.1)
148+
.Field(p => p.Description)
149+
.Value("project description")
150+
.CaseInsensitive(true)
151+
);
152+
153+
//hide
154+
[U]
155+
public void DeserializeShortForm()
156+
{
157+
using var stream = new MemoryStream(ShortFormQuery);
158+
var query = Client.RequestResponseSerializer.Deserialize<ITermQuery>(stream);
159+
query.Should().NotBeNull();
160+
query.Field.Should().Be(new Field("description"));
161+
query.Value.Should().Be("project description");
162+
}
163+
}
107164
}

0 commit comments

Comments
 (0)