Skip to content

Commit 25cc81d

Browse files
committed
added support for $allElementsTrue and $anyElementTrue to aggregation builder.
1 parent 3e3b359 commit 25cc81d

File tree

2 files changed

+67
-22
lines changed

2 files changed

+67
-22
lines changed

src/MongoDB.Driver.Tests/Linq/Translators/AggregateProjectionTranslatorTests_Project.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,26 @@ public async Task Should_translate_add_flattened()
107107
result.Value.Result.Should().Be(43);
108108
}
109109

110+
[Test]
111+
public async Task Should_translate_allElementsTrue()
112+
{
113+
var result = await Project(x => new { Result = x.G.All(g => g.E.F > 30) });
114+
115+
result.Projection.Should().Be("{ Result: { \"$allElementsTrue\" : { \"$map\": { input: \"$G\", as: \"g\", in: { \"$gt\": [\"$$g.E.F\", 30 ] } } } }, _id: 0 }");
116+
117+
result.Value.Result.Should().BeTrue();
118+
}
119+
120+
[Test]
121+
public async Task Should_translate_anyElementTrue()
122+
{
123+
var result = await Project(x => new { Result = x.G.Any(g => g.E.F > 40) });
124+
125+
result.Projection.Should().Be("{ Result: { \"$anyElementTrue\" : { \"$map\": { input: \"$G\", as: \"g\", in: { \"$gt\": [\"$$g.E.F\", 40 ] } } } }, _id: 0 }");
126+
127+
result.Value.Result.Should().BeTrue();
128+
}
129+
110130
[Test]
111131
public async Task Should_translate_and()
112132
{

src/MongoDB.Driver/Linq/Translators/AggregateProjectionTranslator.cs

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,20 @@ private bool TryBuildLinqMethodCall(MethodCallExpression node, out BsonValue res
419419
result = null;
420420
switch (node.Method.Name)
421421
{
422+
case "All":
423+
if(TryBuildMap(node, out result))
424+
{
425+
result = new BsonDocument("$allElementsTrue", result);
426+
return true;
427+
}
428+
break;
429+
case "Any":
430+
if(TryBuildMap(node, out result))
431+
{
432+
result = new BsonDocument("$anyElementTrue", result);
433+
return true;
434+
}
435+
break;
422436
case "Count":
423437
case "LongCount":
424438
if (node.Arguments.Count == 1)
@@ -450,29 +464,8 @@ private bool TryBuildLinqMethodCall(MethodCallExpression node, out BsonValue res
450464
}
451465
break;
452466
case "Select":
453-
var sourceSerializationExpression = node.Arguments[0] as IBsonSerializationInfoExpression;
454-
if (sourceSerializationExpression != null)
467+
if(TryBuildMap(node, out result))
455468
{
456-
var lambda = MongoExpressionVisitor.GetLambda(node.Arguments[1]);
457-
if (lambda.Body is IBsonSerializationInfoExpression)
458-
{
459-
result = ResolveValue(lambda.Body);
460-
return true;
461-
}
462-
463-
var inputValue = ResolveValue(node.Arguments[0]);
464-
var asValue = lambda.Parameters[0].Name;
465-
466-
// HACK: need to add a leading $ sign to the replacement because of how we resolve values.
467-
var body = FieldNameReplacer.Replace(lambda.Body, sourceSerializationExpression.SerializationInfo.ElementName, "$" + asValue);
468-
var inValue = ResolveValue(body);
469-
470-
result = new BsonDocument("$map", new BsonDocument
471-
{
472-
{ "input", inputValue },
473-
{ "as", asValue },
474-
{ "in", inValue }
475-
});
476469
return true;
477470
}
478471
break;
@@ -492,6 +485,38 @@ private bool TryBuildLinqMethodCall(MethodCallExpression node, out BsonValue res
492485
return false;
493486
}
494487

488+
private bool TryBuildMap(MethodCallExpression node, out BsonValue result)
489+
{
490+
result = null;
491+
var sourceSerializationExpression = node.Arguments[0] as IBsonSerializationInfoExpression;
492+
if (sourceSerializationExpression != null)
493+
{
494+
var lambda = MongoExpressionVisitor.GetLambda(node.Arguments[1]);
495+
if (lambda.Body is IBsonSerializationInfoExpression)
496+
{
497+
result = ResolveValue(lambda.Body);
498+
return true;
499+
}
500+
501+
var inputValue = ResolveValue(node.Arguments[0]);
502+
var asValue = lambda.Parameters[0].Name;
503+
504+
// HACK: need to add a leading $ sign to the replacement because of how we resolve values.
505+
var body = FieldNameReplacer.Replace(lambda.Body, sourceSerializationExpression.SerializationInfo.ElementName, "$" + asValue);
506+
var inValue = ResolveValue(body);
507+
508+
result = new BsonDocument("$map", new BsonDocument
509+
{
510+
{ "input", inputValue },
511+
{ "as", asValue },
512+
{ "in", inValue }
513+
});
514+
return true;
515+
}
516+
517+
return false;
518+
}
519+
495520
private bool TryBuildStringMethodCall(MethodCallExpression node, out BsonValue result)
496521
{
497522
result = null;

0 commit comments

Comments
 (0)