Skip to content

Commit c508708

Browse files
committed
Merge pull request #2021 from elastic/fix/verbatim-queries
Verbatim and strict query fixes
2 parents bec619c + 7c5cd19 commit c508708

File tree

105 files changed

+733
-391
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+733
-391
lines changed

Diff for: src/Nest/Aggregations/Bucket/Filter/FilterAggregation.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ public FilterAggregation(string name) : base(name) { }
2222
internal override void WrapInContainer(AggregationContainer c) => c.Filter = this;
2323
}
2424

25-
public class FilterAggregationDescriptor<T>
26-
: BucketAggregationDescriptorBase<FilterAggregationDescriptor<T>,IFilterAggregation, T>
27-
, IFilterAggregation
25+
public class FilterAggregationDescriptor<T>
26+
: BucketAggregationDescriptorBase<FilterAggregationDescriptor<T>,IFilterAggregation, T>
27+
, IFilterAggregation
2828
where T : class
2929
{
3030
QueryContainer IFilterAggregation.Filter { get; set; }
3131

3232
public FilterAggregationDescriptor<T> Filter(Func<QueryContainerDescriptor<T>, QueryContainer> selector) =>
33-
Assign(a=> a.Filter = selector?.InvokeQuery(new QueryContainerDescriptor<T>()));
33+
Assign(a=> a.Filter = selector?.Invoke(new QueryContainerDescriptor<T>()));
3434

3535
}
36-
}
36+
}

Diff for: src/Nest/Aggregations/Bucket/Filters/FiltersAggregation.cs

+12-12
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,16 @@ public interface IFiltersAggregation : IBucketAggregation
1616
bool? OtherBucket { get; set; }
1717

1818
[JsonProperty("other_bucket_key")]
19-
string OtherBucketKey { get; set; }
19+
string OtherBucketKey { get; set; }
2020
}
2121

2222
public class FiltersAggregation : BucketAggregationBase, IFiltersAggregation
2323
{
2424
public Union<INamedFiltersContainer, List<QueryContainer>> Filters { get; set; }
2525

2626
/// <summary>
27-
/// Gets or sets whether to add a bucket to the response which will contain all documents
28-
/// that do not match any of the given filters.
27+
/// Gets or sets whether to add a bucket to the response which will contain all documents
28+
/// that do not match any of the given filters.
2929
/// When set to <c>true</c>, the other bucket will be returned either in a bucket
3030
/// (named "_other_" by default) if named filters are being used,
3131
/// or as the last bucket if anonymous filters are being used
@@ -35,7 +35,7 @@ public class FiltersAggregation : BucketAggregationBase, IFiltersAggregation
3535
public bool? OtherBucket { get; set; }
3636

3737
/// <summary>
38-
/// Gets or sets the key for the other bucket to a value other than the default "_other_".
38+
/// Gets or sets the key for the other bucket to a value other than the default "_other_".
3939
/// Setting this parameter will implicitly set the <see cref="OtherBucket"/> parameter to true
4040
/// </summary>
4141
public string OtherBucketKey { get; set; }
@@ -47,7 +47,7 @@ public FiltersAggregation(string name) : base(name) { }
4747
internal override void WrapInContainer(AggregationContainer c) => c.Filters = this;
4848
}
4949

50-
public class FiltersAggregationDescriptor<T>
50+
public class FiltersAggregationDescriptor<T>
5151
: BucketAggregationDescriptorBase<FiltersAggregationDescriptor<T>, IFiltersAggregation, T>
5252
, IFiltersAggregation
5353
where T : class
@@ -59,21 +59,21 @@ public class FiltersAggregationDescriptor<T>
5959
string IFiltersAggregation.OtherBucketKey{ get; set; }
6060

6161
/// <summary>
62-
/// Adds a bucket to the response which will contain all documents
63-
/// that do not match any of the given filters.
62+
/// Adds a bucket to the response which will contain all documents
63+
/// that do not match any of the given filters.
6464
/// When set to <c>true</c>, the other bucket will be returned either in a bucket
6565
/// (named "_other_" by default) if named filters are being used,
6666
/// or as the last bucket if anonymous filters are being used
6767
/// When set to <c>false</c>, does not compute
68-
/// the other bucket.
68+
/// the other bucket.
6969
/// </summary>
7070
/// <param name="otherBucket">whether to set the other bucket</param>
7171
/// <returns>the <see cref="FiltersAggregationDescriptor{T}"/></returns>
7272
public FiltersAggregationDescriptor<T> OtherBucket(bool otherBucket = true) =>
7373
Assign(a => a.OtherBucket = otherBucket);
7474

7575
/// <summary>
76-
/// Sets the key for the other bucket to a value other than the default "_other_".
76+
/// Sets the key for the other bucket to a value other than the default "_other_".
7777
/// Setting this parameter will implicitly set the <see cref="OtherBucket"/> parameter to true
7878
/// </summary>
7979
/// <param name="otherBucketKey">the name for the other bucket</param>
@@ -85,10 +85,10 @@ public FiltersAggregationDescriptor<T> NamedFilters(Func<NamedFiltersContainerDe
8585
Assign(a => a.Filters = new Union<INamedFiltersContainer, List<QueryContainer>>(selector?.Invoke(new NamedFiltersContainerDescriptor<T>())?.Value));
8686

8787
public FiltersAggregationDescriptor<T> AnonymousFilters(params Func<QueryContainerDescriptor<T>, QueryContainer>[] selectors) =>
88-
Assign(a => a.Filters = selectors.Select(s=>s?.InvokeQuery(new QueryContainerDescriptor<T>())).ToList());
88+
Assign(a => a.Filters = selectors.Select(s=>s?.Invoke(new QueryContainerDescriptor<T>())).ToList());
8989

9090
public FiltersAggregationDescriptor<T> AnonymousFilters(IEnumerable<Func<QueryContainerDescriptor<T>, QueryContainer>> selectors) =>
91-
Assign(a => a.Filters = selectors.Select(s=>s?.InvokeQuery(new QueryContainerDescriptor<T>())).ToList());
91+
Assign(a => a.Filters = selectors.Select(s=>s?.Invoke(new QueryContainerDescriptor<T>())).ToList());
9292

9393
}
94-
}
94+
}

Diff for: src/Nest/Aggregations/Bucket/Filters/NamedFiltersContainer.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ public NamedFiltersContainerDescriptor() : base(new NamedFiltersContainer()) { }
3131
public NamedFiltersContainerDescriptor<T> Filter(string name, IQueryContainer filter) => Assign(name, filter);
3232

3333
public NamedFiltersContainerDescriptor<T> Filter(string name, Func<QueryContainerDescriptor<T>, QueryContainer> selector) =>
34-
Assign(name, selector?.InvokeQuery(new QueryContainerDescriptor<T>()));
34+
Assign(name, selector?.Invoke(new QueryContainerDescriptor<T>()));
3535

3636
public NamedFiltersContainerDescriptor<T> Filter<TOther>(string name, Func<QueryContainerDescriptor<TOther>, QueryContainer> selector)
3737
where TOther : class =>
38-
Assign(name, selector?.InvokeQuery(new QueryContainerDescriptor<TOther>()));
38+
Assign(name, selector?.Invoke(new QueryContainerDescriptor<TOther>()));
3939

4040
}
4141

Diff for: src/Nest/Aggregations/Bucket/SignificantTerms/SignificantTermsAggregation.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,6 @@ public SignificantTermsAggregationDescriptor<T> Script(Func<ScriptedHeuristicDes
139139
Assign(a => a.Script = scriptSelector?.Invoke(new ScriptedHeuristicDescriptor()));
140140

141141
public SignificantTermsAggregationDescriptor<T> BackgroundFilter(Func<QueryContainerDescriptor<T>, QueryContainer> selector) =>
142-
Assign(a => a.BackgroundFilter = selector?.InvokeQuery(new QueryContainerDescriptor<T>()));
142+
Assign(a => a.BackgroundFilter = selector?.Invoke(new QueryContainerDescriptor<T>()));
143143
}
144144
}

Diff for: src/Nest/CommonAbstractions/Extensions/Extensions.cs

-20
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,6 @@ internal static TReturn InvokeOrDefault<T1, T2, TReturn>(this Func<T1, T2, TRetu
2323
where T1 : class, TReturn where TReturn : class =>
2424
func?.Invoke(@default, param2) ?? @default;
2525

26-
internal static QueryContainer InvokeQuery<T>(
27-
this Func<QueryContainerDescriptor<T>, QueryContainer> f,
28-
QueryContainerDescriptor<T> container)
29-
where T : class
30-
{
31-
var c = f.Invoke(container);
32-
//if query is not conditionless or is verbatim: return a container that holds the query
33-
if (c != null && (!c.IsConditionless || c.IsVerbatim))
34-
return c;
35-
36-
//query is conditionless but the container is marked as strict, throw exception
37-
if (c != null && c.IsStrict)
38-
throw new ArgumentException("Query is conditionless but strict is turned on");
39-
40-
//query is conditionless return an empty container that can later be rewritten
41-
return null;
42-
}
43-
44-
internal static bool IsNullOrConditionless(this QueryContainer c) => c == null || c.IsConditionless;
45-
4626
internal static string GetStringValue(this Enum enumValue)
4727
{
4828
var knownEnum = KnownEnums.Resolve(enumValue);

Diff for: src/Nest/Document/Multiple/DeleteByQuery/DeleteByQueryRequest.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,6 @@ public partial class DeleteByQueryDescriptor<T> : IDeleteByQueryRequest<T>
3131
public DeleteByQueryDescriptor<T> MatchAll() => Assign(a => a.Query = new QueryContainerDescriptor<T>().MatchAll());
3232

3333
public DeleteByQueryDescriptor<T> Query(Func<QueryContainerDescriptor<T>, QueryContainer> querySelector) =>
34-
Assign(a => a.Query = querySelector?.InvokeQuery(new QueryContainerDescriptor<T>()));
34+
Assign(a => a.Query = querySelector?.Invoke(new QueryContainerDescriptor<T>()));
3535
}
3636
}

Diff for: src/Nest/Document/Multiple/Reindex/ReindexRequest.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public ReindexDescriptor(IndexName from, IndexName to)
7575
/// A query to optionally limit the documents to use for the reindex operation.
7676
/// </summary>
7777
public ReindexDescriptor<T> Query(Func<QueryContainerDescriptor<T>, QueryContainer> querySelector) =>
78-
Assign(a => a.Query = querySelector?.InvokeQuery(new QueryContainerDescriptor<T>()));
78+
Assign(a => a.Query = querySelector?.Invoke(new QueryContainerDescriptor<T>()));
7979

8080
/// <summary>
8181
/// A query to optionally limit the documents to use for the reindex operation.

Diff for: src/Nest/Document/Multiple/ReindexOnServer/ReindexSource.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public class ReindexSourceDescriptor : DescriptorBase<ReindexSourceDescriptor, I
3838
Types IReindexSource.Type { get; set; }
3939

4040
public ReindexSourceDescriptor Query<T>(Func<QueryContainerDescriptor<T>, QueryContainer> querySelector) where T : class =>
41-
Assign(a => a.Query = querySelector?.InvokeQuery(new QueryContainerDescriptor<T>()));
41+
Assign(a => a.Query = querySelector?.Invoke(new QueryContainerDescriptor<T>()));
4242

4343
public ReindexSourceDescriptor Sort<T>(Func<SortDescriptor<T>, IPromise<IList<ISort>>> selector) where T : class =>
4444
Assign(a => a.Sort = selector?.Invoke(new SortDescriptor<T>())?.Value);

Diff for: src/Nest/Document/Multiple/UpdateByQuery/UpdateByQueryRequest.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public partial class UpdateByQueryDescriptor<T> : IUpdateByQueryRequest<T>
3737
public UpdateByQueryDescriptor<T> MatchAll() => Assign(a => a.Query = new QueryContainerDescriptor<T>().MatchAll());
3838

3939
public UpdateByQueryDescriptor<T> Query(Func<QueryContainerDescriptor<T>, QueryContainer> querySelector) =>
40-
Assign(a => a.Query = querySelector?.InvokeQuery(new QueryContainerDescriptor<T>()));
40+
Assign(a => a.Query = querySelector?.Invoke(new QueryContainerDescriptor<T>()));
4141

4242
public UpdateByQueryDescriptor<T> Script(string script) => Assign(a => a.Script = (InlineScript)script);
4343

Diff for: src/Nest/Indices/AliasManagement/Alias.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@ public class AliasDescriptor : DescriptorBase<AliasDescriptor, IAlias>, IAlias
3838
public AliasDescriptor IndexRouting(string indexRouting) => Assign(a => a.IndexRouting = indexRouting);
3939
public AliasDescriptor SearchRouting(string searchRouting) => Assign(a => a.SearchRouting = searchRouting);
4040
public AliasDescriptor Filter<T>(Func<QueryContainerDescriptor<T>, QueryContainer> filterSelector) where T : class =>
41-
Assign(a => a.Filter = filterSelector?.InvokeQuery(new QueryContainerDescriptor<T>()));
41+
Assign(a => a.Filter = filterSelector?.Invoke(new QueryContainerDescriptor<T>()));
4242
}
4343
}

Diff for: src/Nest/Indices/AliasManagement/Alias/Actions/AliasAdd.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public AliasAddDescriptor SearchRouting(string searchRouting)
6363
public AliasAddDescriptor Filter<T>(Func<QueryContainerDescriptor<T>, QueryContainer> filterSelector)
6464
where T : class
6565
{
66-
Self.Add.Filter = filterSelector?.InvokeQuery(new QueryContainerDescriptor<T>());
66+
Self.Add.Filter = filterSelector?.Invoke(new QueryContainerDescriptor<T>());
6767
return this;
6868
}
6969
}

Diff for: src/Nest/Indices/AliasManagement/PutAlias/PutAliasRequest.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,6 @@ public partial class PutAliasDescriptor
3030

3131
public PutAliasDescriptor Filter<T>(Func<QueryContainerDescriptor<T>, QueryContainer> filterSelector)
3232
where T : class =>
33-
Assign(a => a.Filter = filterSelector?.InvokeQuery(new QueryContainerDescriptor<T>()));
33+
Assign(a => a.Filter = filterSelector?.Invoke(new QueryContainerDescriptor<T>()));
3434
}
3535
}

Diff for: src/Nest/QueryDsl/Abstractions/Container/IQueryContainer.cs

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ public interface IQueryContainer
1515
[JsonIgnore]
1616
bool IsVerbatim { get; set; }
1717

18+
[JsonIgnore]
19+
bool IsWritable { get; }
20+
1821
[JsonIgnore]
1922
IRawQuery RawQuery { get; set; }
2023

Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
using System.Linq;
1+
using System;
2+
using System.Linq;
23

34
namespace Nest
45
{
56
internal static class QueryContainerExtensions
67
{
7-
public static bool IsConditionless(this QueryContainer q) => q == null || q.IsConditionless;
8+
public static bool IsConditionless(this QueryContainer q) => q == null || (q.IsConditionless);
89
}
910

1011
public partial class QueryContainer : IQueryContainer, IDescriptor
@@ -15,47 +16,48 @@ public partial class QueryContainer : IQueryContainer, IDescriptor
1516
bool IQueryContainer.IsStrict { get; set; }
1617
internal bool IsStrict => Self.IsStrict;
1718

19+
bool IQueryContainer.IsWritable => Self.IsVerbatim || !Self.IsConditionless;
20+
internal bool IsWritable => Self.IsWritable;
21+
1822
bool IQueryContainer.IsVerbatim { get; set; }
1923
internal bool IsVerbatim => Self.IsVerbatim;
2024

21-
public QueryContainer()
22-
{
23-
}
24-
25+
public QueryContainer() { }
26+
2527
public QueryContainer(QueryBase query) : this()
2628
{
2729
query?.WrapInContainer(this);
2830
}
29-
31+
3032
public static QueryContainer operator &(QueryContainer leftContainer, QueryContainer rightContainer)
3133
{
3234
QueryContainer queryContainer;
33-
return IfEitherIsEmptyReturnTheOtherOrEmpty(leftContainer, rightContainer, out queryContainer)
34-
? queryContainer
35+
return IfEitherIsEmptyReturnTheOtherOrEmpty(leftContainer, rightContainer, out queryContainer)
36+
? queryContainer
3537
: leftContainer.CombineAsMust(rightContainer);
3638
}
37-
39+
3840
public static QueryContainer operator |(QueryContainer leftContainer, QueryContainer rightContainer)
3941
{
4042
QueryContainer queryContainer;
41-
return IfEitherIsEmptyReturnTheOtherOrEmpty(leftContainer, rightContainer, out queryContainer)
42-
? queryContainer
43+
return IfEitherIsEmptyReturnTheOtherOrEmpty(leftContainer, rightContainer, out queryContainer)
44+
? queryContainer
4345
: leftContainer.CombineAsShould(rightContainer);
4446
}
4547

4648
private static bool IfEitherIsEmptyReturnTheOtherOrEmpty(QueryContainer leftContainer, QueryContainer rightContainer, out QueryContainer queryContainer)
4749
{
4850
var combined = new[] {leftContainer, rightContainer};
49-
var any = combined.Any(bf => bf == null || bf.IsConditionless);
50-
queryContainer = any ? combined.FirstOrDefault(bf => bf != null && !bf.IsConditionless) : null;
51-
return any;
51+
var anyEmpty = combined.Any(q => q == null || !q.IsWritable);
52+
queryContainer = anyEmpty ? combined.FirstOrDefault(q => q != null && q.IsWritable) : null;
53+
return anyEmpty;
5254
}
5355

54-
public static QueryContainer operator !(QueryContainer queryContainer) => queryContainer == null || queryContainer.IsConditionless
56+
public static QueryContainer operator !(QueryContainer queryContainer) => queryContainer == null || (!queryContainer.IsWritable)
5557
? null
5658
: new QueryContainer(new BoolQuery {MustNot = new[] {queryContainer}});
5759

58-
public static QueryContainer operator +(QueryContainer queryContainer) => queryContainer == null || queryContainer.IsConditionless
60+
public static QueryContainer operator +(QueryContainer queryContainer) => queryContainer == null || (!queryContainer.IsWritable)
5961
? null
6062
: new QueryContainer(new BoolQuery {Filter = new[] {queryContainer}});
6163

@@ -69,5 +71,4 @@ public void Accept(IQueryVisitor visitor)
6971
new QueryWalker().Walk(this, visitor);
7072
}
7173
}
72-
7374
}

0 commit comments

Comments
 (0)