Skip to content

Commit 1174569

Browse files
russcamMpdreamz
authored andcommitted
Assert that container level Strict and Verbatim setting are noops
Simplified boolean IsConditionless logic - exit early if individual clause predicates do not match and check in the order is which (I expect) they're most commonly used
1 parent 53bad03 commit 1174569

File tree

3 files changed

+161
-14
lines changed

3 files changed

+161
-14
lines changed

Diff for: src/Nest/QueryDsl/Abstractions/Query/QueryBase.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public abstract class QueryBase : IQuery
3434
public double? Boost { get; set; }
3535
public bool IsVerbatim { get; set; }
3636
public bool IsStrict { get; set; }
37-
public bool IsWritable { get { return this.IsVerbatim || !this.Conditionless; } }
37+
public bool IsWritable => this.IsVerbatim || !this.Conditionless;
3838

3939
bool IQuery.Conditionless => this.Conditionless;
4040
protected abstract bool Conditionless { get; }

Diff for: src/Nest/QueryDsl/Compound/Bool/BoolQuery.cs

+17-13
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ public interface IBoolQuery : IQuery
1616
IEnumerable<QueryContainer> Must { get; set; }
1717

1818
/// <summary>
19-
/// The clause (query) must not appear in the matching documents. Note that it is not possible to search on documents that only consists of a must_not clauses.
19+
/// The clause (query) must not appear in the matching documents.
20+
/// Note that it is not possible to search on documents that only consists of a must_not clauses.
2021
/// </summary>
2122
[JsonProperty("must_not", DefaultValueHandling = DefaultValueHandling.Ignore)]
2223
IEnumerable<QueryContainer> MustNot { get; set; }
2324

2425
/// <summary>
2526
/// The clause (query) should appear in the matching document. A boolean query with no must clauses, one or more should clauses must match a document.
26-
/// The minimum number of should clauses to match can be set using minimum_should_match parameter.
27+
/// The minimum number of should clauses to match can be set using <see cref="MinimumShouldMatch"/>.
2728
/// </summary>
2829
[JsonProperty("should", DefaultValueHandling = DefaultValueHandling.Ignore)]
2930
IEnumerable<QueryContainer> Should { get; set; }
@@ -69,7 +70,7 @@ public class BoolQuery : QueryBase, IBoolQuery
6970

7071
/// <summary>
7172
/// The clause (query) should appear in the matching document. A boolean query with no must clauses, one or more should clauses must match a document.
72-
/// The minimum number of should clauses to match can be set using minimum_should_match parameter.
73+
/// The minimum number of should clauses to match can be set using <see cref="MinimumShouldMatch"/>.
7374
/// </summary>
7475
public IEnumerable<QueryContainer> Should { get; set; }
7576

@@ -96,15 +97,18 @@ public class BoolQuery : QueryBase, IBoolQuery
9697
protected override bool Conditionless => IsConditionless(this);
9798
internal static bool IsConditionless(IBoolQuery q)
9899
{
99-
if (!q.Must.HasAny() && !q.Should.HasAny() && !q.MustNot.HasAny() && !q.Filter.HasAny())
100-
return true;
100+
var musts = q.Must == null || q.Must.All(qq => qq.IsConditionless());
101+
if (!musts) return false;
102+
103+
var shoulds = q.Should == null || q.Should.All(qq => qq.IsConditionless());
104+
if (!shoulds) return false;
105+
106+
var filters = q.Filter == null || q.Filter.All(qq => qq.IsConditionless());
107+
if (!filters) return false;
101108

102-
var mustNots = q.MustNot == null || q.MustNot.HasAny() && q.MustNot.All(qq => qq.IsConditionless());
103-
var shoulds = q.Should == null || q.Should.HasAny() && q.Should.All(qq => qq.IsConditionless());
104-
var musts = q.Must == null || q.Must.HasAny() && q.Must.All(qq => qq.IsConditionless());
105-
var filters = q.Filter == null || (q.Filter.HasAny() && q.Filter.All(qq => qq.IsConditionless()));
109+
var mustNots = q.MustNot == null || q.MustNot.All(qq => qq.IsConditionless());
106110

107-
return mustNots && shoulds && musts && filters;
111+
return mustNots;
108112
}
109113
}
110114

@@ -182,7 +186,7 @@ public BoolQueryDescriptor<T> MustNot(params QueryContainer[] queries) =>
182186

183187
/// <summary>
184188
/// The clause (query) should appear in the matching document. A boolean query with no must clauses, one or more should clauses must match a document.
185-
/// The minimum number of should clauses to match can be set using minimum_should_match parameter.
189+
/// The minimum number of should clauses to match can be set using <see cref="MinimumShouldMatch"/>.
186190
/// </summary>
187191
/// <param name="queries"></param>
188192
/// <returns></returns>
@@ -191,7 +195,7 @@ public BoolQueryDescriptor<T> Should(params Func<QueryContainerDescriptor<T>, Qu
191195

192196
/// <summary>
193197
/// The clause (query) should appear in the matching document. A boolean query with no must clauses, one or more should clauses must match a document.
194-
/// The minimum number of should clauses to match can be set using minimum_should_match parameter.
198+
/// The minimum number of should clauses to match can be set using <see cref="MinimumShouldMatch"/>.
195199
/// </summary>
196200
/// <param name="queries"></param>
197201
/// <returns></returns>
@@ -200,7 +204,7 @@ public BoolQueryDescriptor<T> Should(IEnumerable<Func<QueryContainerDescriptor<T
200204

201205
/// <summary>
202206
/// The clause (query) should appear in the matching document. A boolean query with no must clauses, one or more should clauses must match a document.
203-
/// The minimum number of should clauses to match can be set using minimum_should_match parameter.
207+
/// The minimum number of should clauses to match can be set using <see cref="MinimumShouldMatch"/>.
204208
/// </summary>
205209
/// <param name="queries"></param>
206210
/// <returns></returns>

Diff for: src/Tests/QueryDsl/VerbatimAndStrictQueryUsageTests.cs

+143
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,149 @@
1212

1313
namespace Tests.QueryDsl
1414
{
15+
/** Setting `IsStrict` on the outer query container is a noop */
16+
public class QueryContainerStrictQueryUsageTests : QueryDslUsageTestsBase
17+
{
18+
protected override bool SupportsDeserialization => false;
19+
20+
public QueryContainerStrictQueryUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : base(cluster, usage) { }
21+
22+
protected override object QueryJson => new
23+
{
24+
@bool = new
25+
{
26+
must = new object[]
27+
{
28+
new
29+
{
30+
term = new
31+
{
32+
name = new
33+
{
34+
value = "foo"
35+
}
36+
}
37+
}
38+
}
39+
}
40+
};
41+
42+
protected override QueryContainer QueryInitializer
43+
{
44+
get
45+
{
46+
IQueryContainer query = new QueryContainer(new BoolQuery
47+
{
48+
Must = new List<QueryContainer>
49+
{
50+
new TermQuery
51+
{
52+
Field = "description",
53+
Value = ""
54+
},
55+
new TermQuery
56+
{
57+
Field = "name",
58+
Value = "foo"
59+
}
60+
}
61+
});
62+
63+
query.IsStrict = true;
64+
return (QueryContainer)query;
65+
}
66+
}
67+
68+
#pragma warning disable 618
69+
protected override QueryContainer QueryFluent(QueryContainerDescriptor<Project> q) => q
70+
.Strict()
71+
.Bool(b => b
72+
.Must(qt => qt
73+
.Term(t => t
74+
.Field(p => p.Description)
75+
.Value("")
76+
), qt => qt
77+
.Term(t => t
78+
.Field(p => p.Name)
79+
.Value("foo")
80+
)
81+
)
82+
);
83+
#pragma warning restore 618
84+
}
85+
86+
/** Setting `IsVerbatim` on the outer query container is a noop */
87+
public class QueryContainerVerbatimQueryUsageTests : QueryDslUsageTestsBase
88+
{
89+
protected override bool SupportsDeserialization => false;
90+
91+
public QueryContainerVerbatimQueryUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : base(cluster, usage) { }
92+
93+
protected override object QueryJson => new
94+
{
95+
@bool = new
96+
{
97+
must = new object[]
98+
{
99+
new
100+
{
101+
term = new
102+
{
103+
name = new
104+
{
105+
value = "foo"
106+
}
107+
}
108+
}
109+
}
110+
}
111+
};
112+
113+
protected override QueryContainer QueryInitializer
114+
{
115+
get
116+
{
117+
IQueryContainer query = new QueryContainer(new BoolQuery
118+
{
119+
Must = new List<QueryContainer>
120+
{
121+
new TermQuery
122+
{
123+
Field = "description",
124+
Value = ""
125+
},
126+
new TermQuery
127+
{
128+
Field = "name",
129+
Value = "foo"
130+
}
131+
}
132+
});
133+
134+
query.IsVerbatim = true;
135+
return (QueryContainer)query;
136+
}
137+
}
138+
139+
#pragma warning disable 618
140+
protected override QueryContainer QueryFluent(QueryContainerDescriptor<Project> q) => q
141+
.Verbatim()
142+
.Bool(b => b
143+
.Must(qt => qt
144+
.Term(t => t
145+
.Field(p => p.Description)
146+
.Value("")
147+
), qt => qt
148+
.Term(t => t
149+
.Field(p => p.Name)
150+
.Value("foo")
151+
)
152+
)
153+
);
154+
#pragma warning restore 618
155+
}
156+
157+
/** `IsVerbatim` should be set on individual queries to take effect */
15158
public class CompoundVerbatimQueryUsageTests : QueryDslUsageTestsBase
16159
{
17160
protected override bool SupportsDeserialization => false;

0 commit comments

Comments
 (0)