Skip to content

Commit fdb6fa7

Browse files
committed
rebase on main to pull in the filter limit optimization work
1 parent a416316 commit fdb6fa7

File tree

4 files changed

+454
-74
lines changed

4 files changed

+454
-74
lines changed

tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp4443ArrayOfArraysTests.cs

Lines changed: 143 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919
using MongoDB.Bson;
2020
using MongoDB.Bson.Serialization.Attributes;
2121
using MongoDB.Bson.Serialization.Options;
22+
using MongoDB.Driver.Core.Misc;
2223
using Xunit;
2324

2425
namespace MongoDB.Driver.Tests.Linq.Linq3Implementation.Jira;
2526

2627
public class CSharp4443ArrayOfArraysTests : LinqIntegrationTest<CSharp4443ArrayOfArraysTests.ClassFixture>
2728
{
29+
private static readonly bool FilterLimitIsSupported = Feature.FilterLimit.IsSupported(CoreTestConfiguration.MaxWireVersion);
30+
2831
public CSharp4443ArrayOfArraysTests(ClassFixture fixture)
2932
: base(fixture)
3033
{
@@ -129,7 +132,15 @@ public void Select_DictionaryAsArrayOfArrays_First_should_work()
129132
.Select(x => x.Dictionary.First(kvp => kvp.Key == "age").Value);
130133

131134
var stages = Translate(collection, queryable);
132-
AssertStages(stages, "{ $project : { _v : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$Dictionary', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] } } }, 0] }, 1] }, _id : 0 } }");
135+
136+
if (FilterLimitIsSupported)
137+
{
138+
AssertStages(stages, "{ $project : { _v : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$Dictionary', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] }, limit : 1 } }, 0] }, 1] }, _id : 0 } }");
139+
}
140+
else
141+
{
142+
AssertStages(stages, "{ $project : { _v : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$Dictionary', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] } } }, 0] }, 1] }, _id : 0 } }");
143+
}
133144

134145
var results = queryable.ToList();
135146
results.Should().Equal(25, 30, 35, 130);
@@ -144,7 +155,15 @@ public void Select_DictionaryAsArrayOfArrays_FirstOrDefault_should_work()
144155
.Select(x => x.Dictionary.FirstOrDefault(kvp => kvp.Key.StartsWith("l")).Value);
145156

146157
var stages = Translate(collection, queryable);
147-
AssertStages(stages, "{ $project : { _v : { $arrayElemAt : [{ $let : { vars : { values : { $filter : { input : '$Dictionary', as : 'kvp', cond : { $eq : [{ $indexOfCP : [{ $arrayElemAt : ['$$kvp', 0] }, 'l'] }, 0] } } } }, in : { $cond : { if : { $eq : [{ $size : '$$values' }, 0] }, then : [null, 0], else : { $arrayElemAt : ['$$values', 0] } } } } }, 1] }, _id : 0 } }");
158+
159+
if (FilterLimitIsSupported)
160+
{
161+
AssertStages(stages, "{ $project : { _v : { $arrayElemAt : [{ $let : { vars : { values : { $filter : { input : '$Dictionary', as : 'kvp', cond : { $eq : [{ $indexOfCP : [{ $arrayElemAt : ['$$kvp', 0] }, 'l'] }, 0] }, limit : 1 } } }, in : { $cond : { if : { $eq : [{ $size : '$$values' }, 0] }, then : [null, 0], else : { $arrayElemAt : ['$$values', 0] } } } } }, 1] }, _id : 0 } }");
162+
}
163+
else
164+
{
165+
AssertStages(stages, "{ $project : { _v : { $arrayElemAt : [{ $let : { vars : { values : { $filter : { input : '$Dictionary', as : 'kvp', cond : { $eq : [{ $indexOfCP : [{ $arrayElemAt : ['$$kvp', 0] }, 'l'] }, 0] } } } }, in : { $cond : { if : { $eq : [{ $size : '$$values' }, 0] }, then : [null, 0], else : { $arrayElemAt : ['$$values', 0] } } } } }, 1] }, _id : 0 } }");
166+
}
148167

149168
var results = queryable.ToList();
150169
results.Should().Equal(42, 41, 0, 0);
@@ -159,7 +178,15 @@ public void Select_DictionaryAsArrayOfArrays_IndexerAccess_should_work()
159178
.Select(x => x.Dictionary["age"]);
160179

161180
var stages = Translate(collection, queryable);
162-
AssertStages(stages, "{ $project : { _v : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$Dictionary', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] }, limit : 1 } }, 0] }, 1] }, _id : 0 } }");
181+
182+
if (FilterLimitIsSupported)
183+
{
184+
AssertStages(stages, "{ $project : { _v : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$Dictionary', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] }, limit : 1 } }, 0] }, 1] }, _id : 0 } }");
185+
}
186+
else
187+
{
188+
AssertStages(stages, "{ $project : { _v : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$Dictionary', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] } } }, 0] }, 1] }, _id : 0 } }");
189+
}
163190

164191
var results = queryable.ToList();
165192
results.Should().Equal(25, 30, 35, 130);
@@ -311,7 +338,15 @@ public void Select_IDictionaryAsArrayOfArrays_First_should_work()
311338
.Select(x => x.DictionaryInterface.First(kvp => kvp.Key == "age").Value);
312339

313340
var stages = Translate(collection, queryable);
314-
AssertStages(stages, "{ $project : { _v : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$DictionaryInterface', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] } } }, 0] }, 1] }, _id : 0 } }");
341+
342+
if (FilterLimitIsSupported)
343+
{
344+
AssertStages(stages, "{ $project : { _v : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$DictionaryInterface', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] }, limit : 1 } }, 0] }, 1] }, _id : 0 } }");
345+
}
346+
else
347+
{
348+
AssertStages(stages, "{ $project : { _v : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$DictionaryInterface', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] } } }, 0] }, 1] }, _id : 0 } }");
349+
}
315350

316351
var results = queryable.ToList();
317352
results.Should().Equal(25, 30, 35, 130);
@@ -326,7 +361,15 @@ public void Select_IDictionaryAsArrayOfArrays_FirstOrDefault_should_work()
326361
.Select(x => x.DictionaryInterface.FirstOrDefault(kvp => kvp.Key.StartsWith("l")).Value);
327362

328363
var stages = Translate(collection, queryable);
329-
AssertStages(stages, "{ $project : { _v : { $arrayElemAt : [{ $let : { vars : { values : { $filter : { input : '$DictionaryInterface', as : 'kvp', cond : { $eq : [{ $indexOfCP : [{ $arrayElemAt : ['$$kvp', 0] }, 'l'] }, 0] } } } }, in : { $cond : { if : { $eq : [{ $size : '$$values' }, 0] }, then : [null, 0], else : { $arrayElemAt : ['$$values', 0] } } } } }, 1] }, _id : 0 } }");
364+
365+
if (FilterLimitIsSupported)
366+
{
367+
AssertStages(stages, "{ $project : { _v : { $arrayElemAt : [{ $let : { vars : { values : { $filter : { input : '$DictionaryInterface', as : 'kvp', cond : { $eq : [{ $indexOfCP : [{ $arrayElemAt : ['$$kvp', 0] }, 'l'] }, 0] }, limit : 1 } } }, in : { $cond : { if : { $eq : [{ $size : '$$values' }, 0] }, then : [null, 0], else : { $arrayElemAt : ['$$values', 0] } } } } }, 1] }, _id : 0 } }");
368+
}
369+
else
370+
{
371+
AssertStages(stages, "{ $project : { _v : { $arrayElemAt : [{ $let : { vars : { values : { $filter : { input : '$DictionaryInterface', as : 'kvp', cond : { $eq : [{ $indexOfCP : [{ $arrayElemAt : ['$$kvp', 0] }, 'l'] }, 0] } } } }, in : { $cond : { if : { $eq : [{ $size : '$$values' }, 0] }, then : [null, 0], else : { $arrayElemAt : ['$$values', 0] } } } } }, 1] }, _id : 0 } }");
372+
}
330373

331374
var results = queryable.ToList();
332375
results.Should().Equal(42, 41, 0, 0);
@@ -341,7 +384,15 @@ public void Select_IDictionaryAsArrayOfArrays_IndexerAccess_should_work()
341384
.Select(x => x.DictionaryInterface["age"]);
342385

343386
var stages = Translate(collection, queryable);
344-
AssertStages(stages, "{ $project : { _v : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$DictionaryInterface', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] }, limit : 1 } }, 0] }, 1] }, _id : 0 } }");
387+
388+
if (FilterLimitIsSupported)
389+
{
390+
AssertStages(stages, "{ $project : { _v : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$DictionaryInterface', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] }, limit : 1 } }, 0] }, 1] }, _id : 0 } }");
391+
}
392+
else
393+
{
394+
AssertStages(stages, "{ $project : { _v : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$DictionaryInterface', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] } } }, 0] }, 1] }, _id : 0 } }");
395+
}
345396

346397
var results = queryable.ToList();
347398
results.Should().Equal(25, 30, 35, 130);
@@ -512,7 +563,15 @@ public void Where_DictionaryAsArrayOfArrays_First_should_work()
512563
.Where(x => x.Dictionary.First(kvp => kvp.Key.StartsWith("l")).Value > 40);
513564

514565
var stages = Translate(collection, queryable);
515-
AssertStages(stages, "{ $match : { $expr : { $gt : [{ $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$Dictionary', as : 'kvp', cond : { $eq : [{ $indexOfCP : [{ $arrayElemAt : ['$$kvp', 0] }, 'l'] }, 0] } } }, 0] }, 1] }, 40] } } }");
566+
567+
if (FilterLimitIsSupported)
568+
{
569+
AssertStages(stages, "{ $match : { $expr : { $gt : [{ $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$Dictionary', as : 'kvp', cond : { $eq : [{ $indexOfCP : [{ $arrayElemAt : ['$$kvp', 0] }, 'l'] }, 0] }, limit : 1 } }, 0] }, 1] }, 40] } } }");
570+
}
571+
else
572+
{
573+
AssertStages(stages, "{ $match : { $expr : { $gt : [{ $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$Dictionary', as : 'kvp', cond : { $eq : [{ $indexOfCP : [{ $arrayElemAt : ['$$kvp', 0] }, 'l'] }, 0] } } }, 0] }, 1] }, 40] } } }");
574+
}
516575

517576
var result = queryable.ToList();
518577
result.Should().HaveCount(2);
@@ -641,11 +700,23 @@ public void Where_DictionaryAsArrayOfArrays_OrderBy_should_work()
641700
.OrderBy(x => x.Dictionary["age"]);
642701

643702
var stages = Translate(collection, queryable);
644-
AssertStages(stages,
645-
"{ $match : { Dictionary : { $elemMatch : { '0' : 'age' } } } }",
646-
"{ $project : { _id : 0, _document : '$$ROOT', _key1 : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$Dictionary', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] }, limit : 1 } }, 0] }, 1] } } }",
647-
"{ $sort : { _key1 : 1 } }",
648-
"{ $replaceRoot : { newRoot : '$_document' } }");
703+
704+
if (FilterLimitIsSupported)
705+
{
706+
AssertStages(stages,
707+
"{ $match : { Dictionary : { $elemMatch : { '0' : 'age' } } } }",
708+
"{ $project : { _id : 0, _document : '$$ROOT', _key1 : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$Dictionary', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] }, limit : 1 } }, 0] }, 1] } } }",
709+
"{ $sort : { _key1 : 1 } }",
710+
"{ $replaceRoot : { newRoot : '$_document' } }");
711+
}
712+
else
713+
{
714+
AssertStages(stages,
715+
"{ $match : { Dictionary : { $elemMatch : { '0' : 'age' } } } }",
716+
"{ $project : { _id : 0, _document : '$$ROOT', _key1 : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$Dictionary', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] } } }, 0] }, 1] } } }",
717+
"{ $sort : { _key1 : 1 } }",
718+
"{ $replaceRoot : { newRoot : '$_document' } }");
719+
}
649720

650721
var result = queryable.ToList();
651722
result.Should().HaveCount(4);
@@ -662,11 +733,23 @@ public void Where_DictionaryAsArrayOfArrays_OrderByDescending_should_work()
662733
.OrderByDescending(x => x.Dictionary["age"]);
663734

664735
var stages = Translate(collection, queryable);
665-
AssertStages(stages,
666-
"{ $match : { Dictionary : { $elemMatch : { '0' : 'age' } } } }",
667-
"{ $project : { _id : 0, _document : '$$ROOT', _key1 : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$Dictionary', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] }, limit : 1 } }, 0] }, 1] } } }",
668-
"{ $sort : { _key1 : -1 } }",
669-
"{ $replaceRoot : { newRoot : '$_document' } }");
736+
737+
if (FilterLimitIsSupported)
738+
{
739+
AssertStages(stages,
740+
"{ $match : { Dictionary : { $elemMatch : { '0' : 'age' } } } }",
741+
"{ $project : { _id : 0, _document : '$$ROOT', _key1 : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$Dictionary', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] }, limit : 1 } }, 0] }, 1] } } }",
742+
"{ $sort : { _key1 : -1 } }",
743+
"{ $replaceRoot : { newRoot : '$_document' } }");
744+
}
745+
else
746+
{
747+
AssertStages(stages,
748+
"{ $match : { Dictionary : { $elemMatch : { '0' : 'age' } } } }",
749+
"{ $project : { _id : 0, _document : '$$ROOT', _key1 : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$Dictionary', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] } } }, 0] }, 1] } } }",
750+
"{ $sort : { _key1 : -1 } }",
751+
"{ $replaceRoot : { newRoot : '$_document' } }");
752+
}
670753

671754
var result = queryable.ToList();
672755
result.Should().HaveCount(4);
@@ -758,7 +841,15 @@ public void Where_IDictionaryAsArrayOfArrays_First_should_work()
758841
.Where(x => x.DictionaryInterface.First(kvp => kvp.Key.StartsWith("l")).Value > 40);
759842

760843
var stages = Translate(collection, queryable);
761-
AssertStages(stages, "{ $match : { $expr : { $gt : [{ $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$DictionaryInterface', as : 'kvp', cond : { $eq : [{ $indexOfCP : [{ $arrayElemAt : ['$$kvp', 0] }, 'l'] }, 0] } } }, 0] }, 1] }, 40] } } }");
844+
845+
if (FilterLimitIsSupported)
846+
{
847+
AssertStages(stages, "{ $match : { $expr : { $gt : [{ $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$DictionaryInterface', as : 'kvp', cond : { $eq : [{ $indexOfCP : [{ $arrayElemAt : ['$$kvp', 0] }, 'l'] }, 0] }, limit : 1 } }, 0] }, 1] }, 40] } } }");
848+
}
849+
else
850+
{
851+
AssertStages(stages, "{ $match : { $expr : { $gt : [{ $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$DictionaryInterface', as : 'kvp', cond : { $eq : [{ $indexOfCP : [{ $arrayElemAt : ['$$kvp', 0] }, 'l'] }, 0] } } }, 0] }, 1] }, 40] } } }");
852+
}
762853

763854
var result = queryable.ToList();
764855
result.Should().HaveCount(2);
@@ -887,11 +978,23 @@ public void Where_IDictionaryAsArrayOfArrays_OrderBy_should_work()
887978
.OrderBy(x => x.DictionaryInterface["age"]);
888979

889980
var stages = Translate(collection, queryable);
890-
AssertStages(stages,
891-
"{ $match : { DictionaryInterface : { $elemMatch : { '0' : 'age' } } } }",
892-
"{ $project : { _id : 0, _document : '$$ROOT', _key1 : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$DictionaryInterface', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] }, limit : 1 } }, 0] }, 1] } } }",
893-
"{ $sort : { _key1 : 1 } }",
894-
"{ $replaceRoot : { newRoot : '$_document' } }");
981+
982+
if (FilterLimitIsSupported)
983+
{
984+
AssertStages(stages,
985+
"{ $match : { DictionaryInterface : { $elemMatch : { '0' : 'age' } } } }",
986+
"{ $project : { _id : 0, _document : '$$ROOT', _key1 : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$DictionaryInterface', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] }, limit : 1 } }, 0] }, 1] } } }",
987+
"{ $sort : { _key1 : 1 } }",
988+
"{ $replaceRoot : { newRoot : '$_document' } }");
989+
}
990+
else
991+
{
992+
AssertStages(stages,
993+
"{ $match : { DictionaryInterface : { $elemMatch : { '0' : 'age' } } } }",
994+
"{ $project : { _id : 0, _document : '$$ROOT', _key1 : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$DictionaryInterface', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] } } }, 0] }, 1] } } }",
995+
"{ $sort : { _key1 : 1 } }",
996+
"{ $replaceRoot : { newRoot : '$_document' } }");
997+
}
895998

896999
var result = queryable.ToList();
8971000
result.Should().HaveCount(4);
@@ -908,11 +1011,23 @@ public void Where_IDictionaryAsArrayOfArrays_OrderByDescending_should_work()
9081011
.OrderByDescending(x => x.DictionaryInterface["age"]);
9091012

9101013
var stages = Translate(collection, queryable);
911-
AssertStages(stages,
912-
"{ $match : { DictionaryInterface : { $elemMatch : { '0' : 'age' } } } }",
913-
"{ $project : { _id : 0, _document : '$$ROOT', _key1 : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$DictionaryInterface', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] }, limit : 1 } }, 0] }, 1] } } }",
914-
"{ $sort : { _key1 : -1 } }",
915-
"{ $replaceRoot : { newRoot : '$_document' } }");
1014+
1015+
if (FilterLimitIsSupported)
1016+
{
1017+
AssertStages(stages,
1018+
"{ $match : { DictionaryInterface : { $elemMatch : { '0' : 'age' } } } }",
1019+
"{ $project : { _id : 0, _document : '$$ROOT', _key1 : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$DictionaryInterface', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] }, limit : 1 } }, 0] }, 1] } } }",
1020+
"{ $sort : { _key1 : -1 } }",
1021+
"{ $replaceRoot : { newRoot : '$_document' } }");
1022+
}
1023+
else
1024+
{
1025+
AssertStages(stages,
1026+
"{ $match : { DictionaryInterface : { $elemMatch : { '0' : 'age' } } } }",
1027+
"{ $project : { _id : 0, _document : '$$ROOT', _key1 : { $arrayElemAt : [{ $arrayElemAt : [{ $filter : { input : '$DictionaryInterface', as : 'kvp', cond : { $eq : [{ $arrayElemAt : ['$$kvp', 0] }, 'age'] } } }, 0] }, 1] } } }",
1028+
"{ $sort : { _key1 : -1 } }",
1029+
"{ $replaceRoot : { newRoot : '$_document' } }");
1030+
}
9161031

9171032
var result = queryable.ToList();
9181033
result.Should().HaveCount(4);

0 commit comments

Comments
 (0)