Skip to content

Commit 44c4d03

Browse files
CSHARP-2804: Support for JavaScript User Defined Functions.
1 parent 58cd0ed commit 44c4d03

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

src/MongoDB.Driver.Core/Core/Misc/Feature.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public class Feature
3333
private static readonly Feature __aggregateCursorResult = new Feature("AggregateCursorResult", new SemanticVersion(2, 6, 0));
3434
private static readonly Feature __aggregateExplain = new Feature("AggregateExplain", new SemanticVersion(2, 6, 0));
3535
private static readonly Feature __aggregateFacetStage = new Feature("AggregateFacetStage", new SemanticVersion(3, 4, 0, "rc0"));
36+
private static readonly Feature __aggregateFunction = new Feature("AggregateFunction", new SemanticVersion(4, 3, 4));
3637
private static readonly Feature __aggregateGraphLookupStage = new Feature("AggregateGraphLookupStage", new SemanticVersion(3, 4, 0, "rc0"));
3738
private static readonly Feature __aggregateHint = new Feature("AggregateHint", new SemanticVersion(3, 6, 0, "rc0"));
3839
private static readonly Feature __aggregateLet = new Feature("AggregateLet", new SemanticVersion(3, 6, 0));
@@ -143,6 +144,11 @@ public class Feature
143144
/// </summary>
144145
public static Feature AggregateFacetStage => __aggregateFacetStage;
145146

147+
/// <summary>
148+
/// Gets the aggregate $function stage feature.
149+
/// </summary>
150+
public static Feature AggregateFunction => __aggregateFunction;
151+
146152
/// <summary>
147153
/// Gets the aggregate $graphLookup stage feature.
148154
/// </summary>

tests/MongoDB.Driver.Tests/AggregateFluentTests.cs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,72 @@ public void Count_should_return_the_expected_result(
196196
result.Should().Be(1);
197197
}
198198

199+
[SkippableFact]
200+
public void Function_should_return_expected_result()
201+
{
202+
RequireServer.Check().Supports(Feature.AggregateFunction);
203+
204+
var client = CreateClient();
205+
var databaseName = "test";
206+
var collectionName = "collection";
207+
DropCollection(client, databaseName, collectionName);
208+
var collection = client.GetDatabase(databaseName).GetCollection<BsonDocument>(collectionName);
209+
var players = new[]
210+
{
211+
BsonDocument.Parse("{ _id : 1, name : 'Miss Cheevous', scores : [ 10, 5, 10 ] }"),
212+
BsonDocument.Parse("{ _id : 2, name : 'Miss Ann Thrope', scores : [ 10, 10, 10 ] }"),
213+
BsonDocument.Parse("{ _id : 3, name : 'Mrs. Eppie Delta', scores : [ 9, 8, 8 ] }")
214+
};
215+
collection.InsertMany(players);
216+
217+
var isFoundFunction = "function(name) { return hex_md5(name) == '15b0a220baa16331e8d80e15367677ad' }";
218+
var messageFunction = "function(name, scores) { let total = Array.sum(scores); return `Hello ${ name}. Your total score is ${ total}.` }";
219+
var isFoundExpression = new BsonDocument
220+
{
221+
{
222+
"$function",
223+
new BsonDocument
224+
{
225+
{ "body", isFoundFunction },
226+
{ "args", new BsonArray { "$name" } },
227+
{ "lang", "js" }
228+
}
229+
},
230+
};
231+
var messageExpression = new BsonDocument
232+
{
233+
{
234+
"$function",
235+
new BsonDocument
236+
{
237+
{ "body", messageFunction },
238+
{ "args", new BsonArray { "$name", "$scores" } },
239+
{ "lang", "js" }
240+
}
241+
},
242+
};
243+
var addFieldsStage = new BsonDocument
244+
{
245+
{
246+
"$addFields",
247+
new BsonDocument
248+
{
249+
{ "isFound", isFoundExpression },
250+
{ "message", messageExpression },
251+
}
252+
}
253+
};
254+
var stages = new[] { addFieldsStage };
255+
var pipeline = new BsonDocumentStagePipelineDefinition<BsonDocument, BsonDocument>(stages);
256+
257+
var result = collection.Aggregate(pipeline).ToList();
258+
259+
result.Count.Should().Be(3);
260+
result[0].Should().Be("{ _id : 1, name : 'Miss Cheevous', scores : [ 10, 5, 10 ], isFound : false, message : 'Hello Miss Cheevous. Your total score is 25.' }");
261+
result[1].Should().Be("{ _id : 2, name : 'Miss Ann Thrope', scores : [ 10, 10, 10 ], isFound : true, message : 'Hello Miss Ann Thrope. Your total score is 30.' }");
262+
result[2].Should().Be("{ _id : 3, name : 'Mrs. Eppie Delta', scores : [ 9, 8, 8 ], isFound : false, message : 'Hello Mrs. Eppie Delta. Your total score is 25.' }");
263+
}
264+
199265
[SkippableFact]
200266
public void Group_with_accumulator_should_return_expected_result()
201267
{

0 commit comments

Comments
 (0)