Skip to content

Commit 4891909

Browse files
committed
Add max_children to Nested Sort (#4596)
This commit adds max_children to nested sort. Closes #4595 (cherry picked from commit 7aa05d9)
1 parent c2a81c3 commit 4891909

File tree

3 files changed

+129
-21
lines changed

3 files changed

+129
-21
lines changed

docs/search/request/sort-usage.asciidoc

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ s => s
3535
.MissingLast()
3636
.UnmappedType(FieldType.Date)
3737
.Mode(SortMode.Average)
38-
.NestedPath(p => p.Tags)
39-
.NestedFilter(q => q.MatchAll())
38+
.Nested(n => n
39+
.Path(p => p.Tags)
40+
.Filter(q => q.MatchAll())
41+
)
4042
)
4143
.Field(f => f
4244
.Field(p => p.NumberOfCommits)
@@ -51,6 +53,10 @@ s => s
5153
.Mode(SortMode.Min)
5254
.Points(new GeoLocation(70, -70), new GeoLocation(-12, 12))
5355
)
56+
.GeoDistance(g => g
57+
.Field(p => p.LocationPoint)
58+
.Points(new GeoLocation(70, -70), new GeoLocation(-12, 12))
59+
)
5460
.Script(sc => sc
5561
.Type("number")
5662
.Ascending()
@@ -82,8 +88,11 @@ new SearchRequest<Project>
8288
Missing = "_last",
8389
UnmappedType = FieldType.Date,
8490
Mode = SortMode.Average,
85-
NestedPath = Field<Project>(p => p.Tags),
86-
NestedFilter = new MatchAllQuery(),
91+
Nested = new NestedSort
92+
{
93+
Path = Field<Project>(p => p.Tags),
94+
Filter = new MatchAllQuery()
95+
}
8796
},
8897
new SortField
8998
{
@@ -100,6 +109,11 @@ new SearchRequest<Project>
100109
Mode = SortMode.Min,
101110
Points = new[] { new GeoLocation(70, -70), new GeoLocation(-12, 12) }
102111
},
112+
new GeoDistanceSort
113+
{
114+
Field = "locationPoint",
115+
Points = new[] { new GeoLocation(70, -70), new GeoLocation(-12, 12) }
116+
},
103117
new ScriptSort
104118
{
105119
Type = "number",
@@ -146,9 +160,11 @@ new SearchRequest<Project>
146160
"missing": "_last",
147161
"order": "desc",
148162
"mode": "avg",
149-
"nested_path": "tags",
150-
"nested_filter": {
151-
"match_all": {}
163+
"nested": {
164+
"path": "tags",
165+
"filter": {
166+
"match_all": {}
167+
}
152168
},
153169
"unmapped_type": "date"
154170
}
@@ -177,6 +193,20 @@ new SearchRequest<Project>
177193
"unit": "cm"
178194
}
179195
},
196+
{
197+
"_geo_distance": {
198+
"locationPoint": [
199+
{
200+
"lat": 70.0,
201+
"lon": -70.0
202+
},
203+
{
204+
"lat": -12.0,
205+
"lon": 12.0
206+
}
207+
]
208+
}
209+
},
180210
{
181211
"_script": {
182212
"order": "asc",
@@ -214,6 +244,7 @@ s => s
214244
.Filter(ff => ff
215245
.MatchAll()
216246
)
247+
.MaxChildren(50)
217248
)
218249
)
219250
)
@@ -238,7 +269,8 @@ new SearchRequest<Project>
238269
Nested = new NestedSort
239270
{
240271
Path = Field<Project>(p => p.Tags),
241-
Filter = new MatchAllQuery()
272+
Filter = new MatchAllQuery(),
273+
MaxChildren = 50
242274
}
243275
}
244276
}
@@ -259,7 +291,8 @@ new SearchRequest<Project>
259291
"path": "tags",
260292
"filter": {
261293
"match_all": {}
262-
}
294+
},
295+
"max_children": 50
263296
},
264297
"unmapped_type": "date"
265298
}

src/Nest/Search/Search/Sort/NestedSort.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,42 +4,80 @@
44

55
namespace Nest
66
{
7+
/// <summary>
8+
/// Sort on a field inside one or more nested objects.
9+
/// </summary>
710
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
811
[JsonConverter(typeof(ReadAsTypeJsonConverter<NestedSort>))]
912
public interface INestedSort
1013
{
14+
/// <summary>
15+
/// A filter that the inner objects inside the nested path should match with in order for its field values to be taken into account
16+
/// by sorting. A common pattern is to repeat the query/filter inside the nested filter or query.
17+
/// By default no nested filter is active.
18+
/// </summary>
1119
[JsonProperty("filter")]
1220
QueryContainer Filter { get; set; }
1321

22+
/// <summary>
23+
/// Same as top-level nested, but applies to another nested path within the current nested object.
24+
/// </summary>
1425
[JsonProperty("nested")]
1526
INestedSort Nested { get; set; }
1627

28+
/// <summary>
29+
/// Defines on which nested object to sort. The actual sort field must be a direct field inside this nested object.
30+
/// When sorting by nested field, this field is mandatory.
31+
/// </summary>
1732
[JsonProperty("path")]
1833
Field Path { get; set; }
34+
35+
/// <summary>
36+
/// The maximum number of children to consider per root document when picking the sort value. Defaults to unlimited.
37+
/// <para />
38+
/// Available in Elasticsearch 6.5.0+
39+
/// </summary>
40+
[JsonProperty("max_children")]
41+
int? MaxChildren { get; set; }
1942
}
2043

44+
/// <inheritdoc />
2145
public class NestedSort : INestedSort
2246
{
47+
/// <inheritdoc />
2348
public QueryContainer Filter { get; set; }
49+
/// <inheritdoc />
2450
public INestedSort Nested { get; set; }
51+
/// <inheritdoc />
2552
public Field Path { get; set; }
53+
/// <inheritdoc />
54+
public int? MaxChildren { get; set; }
2655
}
2756

57+
/// <inheritdoc cref="INestedSort"/>
2858
public class NestedSortDescriptor<T>
2959
: DescriptorBase<NestedSortDescriptor<T>, INestedSort>, INestedSort where T : class
3060
{
3161
QueryContainer INestedSort.Filter { get; set; }
3262
INestedSort INestedSort.Nested { get; set; }
3363
Field INestedSort.Path { get; set; }
64+
int? INestedSort.MaxChildren { get; set; }
3465

66+
/// <inheritdoc cref="INestedSort.Path"/>
3567
public NestedSortDescriptor<T> Path(Field path) => Assign(path, (a, v) => a.Path = v);
3668

69+
/// <inheritdoc cref="INestedSort.Path"/>
3770
public NestedSortDescriptor<T> Path(Expression<Func<T, object>> objectPath) => Assign(objectPath, (a, v) => a.Path = v);
3871

72+
/// <inheritdoc cref="INestedSort.Filter"/>
3973
public NestedSortDescriptor<T> Filter(Func<QueryContainerDescriptor<T>, QueryContainer> filterSelector) =>
4074
Assign(filterSelector, (a, v) => a.Filter = v?.Invoke(new QueryContainerDescriptor<T>()));
4175

76+
/// <inheritdoc cref="INestedSort.Nested"/>
4277
public NestedSortDescriptor<T> Nested(Func<NestedSortDescriptor<T>, INestedSort> filterSelector) =>
4378
Assign(filterSelector, (a, v) => a.Nested = v?.Invoke(new NestedSortDescriptor<T>()));
79+
80+
/// <inheritdoc cref="INestedSort.MaxChildren"/>
81+
public NestedSortDescriptor<T> MaxChildren(int? maxChildren) => Assign(maxChildren, (a, v) => a.MaxChildren = v);
4482
}
4583
}

src/Tests/Tests/Search/Request/SortUsageTests.cs

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,13 @@ public SortUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : base(clust
3535
missing = "_last",
3636
order = "desc",
3737
mode = "avg",
38-
nested_path = "tags",
39-
nested_filter = new
38+
nested = new
4039
{
41-
match_all = new { }
40+
path = "tags",
41+
filter = new
42+
{
43+
match_all = new { }
44+
}
4245
},
4346
unmapped_type = "date"
4447
}
@@ -76,6 +79,25 @@ public SortUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : base(clust
7679
}
7780
},
7881
new
82+
{
83+
_geo_distance = new
84+
{
85+
locationPoint = new[]
86+
{
87+
new
88+
{
89+
lat = 70.0,
90+
lon = -70.0
91+
},
92+
new
93+
{
94+
lat = -12.0,
95+
lon = 12.0
96+
}
97+
}
98+
}
99+
},
100+
new
79101
{
80102
_script = new
81103
{
@@ -106,8 +128,10 @@ public SortUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : base(clust
106128
.MissingLast()
107129
.UnmappedType(FieldType.Date)
108130
.Mode(SortMode.Average)
109-
.NestedPath(p => p.Tags)
110-
.NestedFilter(q => q.MatchAll())
131+
.Nested(n => n
132+
.Path(p => p.Tags)
133+
.Filter(q => q.MatchAll())
134+
)
111135
)
112136
.Field(f => f
113137
.Field(p => p.NumberOfCommits)
@@ -122,6 +146,10 @@ public SortUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : base(clust
122146
.Mode(SortMode.Min)
123147
.Points(new GeoLocation(70, -70), new GeoLocation(-12, 12))
124148
)
149+
.GeoDistance(g => g
150+
.Field(p => p.LocationPoint)
151+
.Points(new GeoLocation(70, -70), new GeoLocation(-12, 12))
152+
)
125153
.Script(sc => sc
126154
.Type("number")
127155
.Ascending()
@@ -149,10 +177,11 @@ public SortUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : base(clust
149177
Missing = "_last",
150178
UnmappedType = FieldType.Date,
151179
Mode = SortMode.Average,
152-
#pragma warning disable 618
153-
NestedPath = Field<Project>(p => p.Tags),
154-
NestedFilter = new MatchAllQuery(),
155-
#pragma warning restore 618
180+
Nested = new NestedSort
181+
{
182+
Path = Field<Project>(p => p.Tags),
183+
Filter = new MatchAllQuery()
184+
}
156185
},
157186
new SortField
158187
{
@@ -169,6 +198,11 @@ public SortUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : base(clust
169198
Mode = SortMode.Min,
170199
Points = new[] { new GeoLocation(70, -70), new GeoLocation(-12, 12) }
171200
},
201+
new GeoDistanceSort
202+
{
203+
Field = "locationPoint",
204+
Points = new[] { new GeoLocation(70, -70), new GeoLocation(-12, 12) }
205+
},
172206
new ScriptSort
173207
{
174208
Type = "number",
@@ -192,7 +226,7 @@ public SortUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : base(clust
192226
* In Elasticsearch 6.1.0+, using `nested_path` and `nested_filter` for sorting on fields mapped as
193227
* `nested` types is deprecated. Instead, you should use the `nested` sort instead.
194228
*/
195-
[SkipVersion("<6.1.0", "Only available in Elasticsearch 6.1.0+")]
229+
[SkipVersion("<6.5.0", "max_children added in Elasticsearch 6.5.0+")]
196230
public class NestedSortUsageTests : SearchUsageTestBase
197231
{
198232
public NestedSortUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : base(cluster, usage) { }
@@ -216,7 +250,8 @@ public NestedSortUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : base
216250
filter = new
217251
{
218252
match_all = new { }
219-
}
253+
},
254+
max_children = 50
220255
},
221256
unmapped_type = "date"
222257
}
@@ -238,6 +273,7 @@ public NestedSortUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : base
238273
.Filter(ff => ff
239274
.MatchAll()
240275
)
276+
.MaxChildren(50)
241277
)
242278
)
243279
);
@@ -257,7 +293,8 @@ public NestedSortUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : base
257293
Nested = new NestedSort
258294
{
259295
Path = Field<Project>(p => p.Tags),
260-
Filter = new MatchAllQuery()
296+
Filter = new MatchAllQuery(),
297+
MaxChildren = 50
261298
}
262299
}
263300
}

0 commit comments

Comments
 (0)