Aggregate methods run MongoDB aggregation pipelines against a collection, returning results as either BSON documents or JSON strings.
| Method | Returns | Description |
|---|---|---|
AggregateAsync |
BsonDocument[] |
Returns BSON documents for C# processing |
AggregateAsJsonAsync |
string |
Returns raw JSON string |
| Method | Use Case |
|---|---|
AggregateAsync |
C# applications that process results programmatically |
AggregateAsJsonAsync |
Web APIs that pass JSON directly to clients |
var pipeline = new BsonDocument[]
{
new BsonDocument("$match", new BsonDocument("_t", "Person")),
new BsonDocument("$group", new BsonDocument
{
["_id"] = "$Department",
["count"] = new BsonDocument("$sum", 1)
}),
new BsonDocument("$sort", new BsonDocument("count", -1))
};
var results = await client.AggregateAsync(instance, "KeepObjects", pipeline);
foreach (var doc in results)
{
var department = doc["_id"].AsString;
var count = doc["count"].AsInt32;
Console.WriteLine($"{department}: {count} people");
}
var pipeline = new BsonDocument[]
{
new BsonDocument("$match", new BsonDocument("_t", "Controller")),
new BsonDocument("$group", new BsonDocument
{
["_id"] = "$Status.IsOnline",
["count"] = new BsonDocument("$sum", 1)
})
};
var jsonResult = await client.AggregateAsJsonAsync(instance, "KeepObjects", pipeline);
// Returns: [{"_id": true, "count": 15}, {"_id": false, "count": 3}]
return Content(jsonResult, "application/json");
Example in C#
// Returns: IEnumerable<String>
var item = await client.AggregateAsJsonAsync(FolderInfo folder, String collectionName, BsonDocument operations, Int32 queryTimeout, Boolean jsonStrict, Boolean includeGlobal, String hints);
The AggregateAsJsonAsync method executes a MongoDB aggregation pipeline and returns the results as raw JSON. This is useful when you need the raw JSON response for custom parsing, logging, or integration with other systems.
public async Task<string> AggregateAsJsonAsync(string instanceId, string typeName, string pipeline)
The AggregateAsJsonAsync method provides direct access to MongoDB aggregation results in JSON format. Unlike AggregateAsync, which deserializes results into typed objects, this method returns raw JSON strings for:
| Parameter | Type | Description |
|---|---|---|
| instanceId | string |
The unique identifier of the Keep instance |
| typeName | string |
The collection type to aggregate (e.g., “CardholderInfo”, “EventInfo”) |
| pipeline | string |
A JSON string representing the MongoDB aggregation pipeline |
| Type | Description |
|---|---|
Task<string> |
Raw JSON string containing the aggregation results |
using Feenics.Keep.WebApi.Wrapper;
using System.Text.Json;
var client = new Client("https://keep.feenics.com");
await client.OpenAsync("username", "password", "my-app");
// Define an aggregation pipeline
string pipeline = @"[
{ ""$match"": { ""Status"": ""Active"" } },
{ ""$group"": {
""_id"": ""$Department"",
""count"": { ""$sum"": 1 }
}},
{ ""$sort"": { ""count"": -1 } }
]";
// Execute aggregation and get raw JSON
string jsonResult = await client.AggregateAsJsonAsync(
instanceId,
"CardholderInfo",
pipeline
);
// Output raw JSON
Console.WriteLine("Raw JSON Result:");
Console.WriteLine(jsonResult);
// Parse if needed
using var doc = JsonDocument.Parse(jsonResult);
foreach (var element in doc.RootElement.EnumerateArray())
{
string dept = element.GetProperty("_id").GetString();
int count = element.GetProperty("count").GetInt32();
Console.WriteLine($" {dept}: {count} cardholders");
}
using Feenics.Keep.WebApi.Wrapper;
using Newtonsoft.Json.Linq;
// Complex aggregation with dynamic results
string pipeline = @"[
{ ""$match"": { ""ServerTimeStampUtc"": { ""$gte"": { ""$date"": """ +
DateTime.UtcNow.AddDays(-7).ToString("o") + @""" } } },
{ ""$group"": {
""_id"": {
""date"": { ""$dateToString"": { ""format"": ""%Y-%m-%d"", ""date"": ""$ServerTimeStampUtc"" } },
""type"": ""$EventType""
},
""count"": { ""$sum"": 1 }
}},
{ ""$sort"": { ""_id.date"": 1 } }
]";
string json = await client.AggregateAsJsonAsync(instanceId, "EventInfo", pipeline);
// Parse with Newtonsoft.Json for dynamic access
JArray results = JArray.Parse(json);
foreach (var item in results)
{
Console.WriteLine($"Date: {item["_id"]["date"]}, Type: {item["_id"]["type"]}, Count: {item["count"]}");
}
using Feenics.Keep.WebApi.Wrapper;
using Microsoft.Extensions.Logging;
public class AggregationService
{
private readonly Client _client;
private readonly ILogger<AggregationService> _logger;
public async Task<string> RunAndLogAggregationAsync(
string instanceId,
string typeName,
string pipeline)
{
_logger.LogDebug("Executing aggregation on {TypeName}", typeName);
_logger.LogTrace("Pipeline: {Pipeline}", pipeline);
try
{
string result = await _client.AggregateAsJsonAsync(
instanceId,
typeName,
pipeline
);
_logger.LogDebug("Aggregation completed. Response size: {Size} bytes",
result.Length);
_logger.LogTrace("Raw result: {Result}", result);
return result;
}
catch (Exception ex)
{
_logger.LogError(ex, "Aggregation failed for {TypeName}", typeName);
throw;
}
}
}
using Feenics.Keep.WebApi.Wrapper;
using System.Net.Http;
public class DataExporter
{
private readonly Client _keepClient;
private readonly HttpClient _httpClient;
public async Task ExportAggregationToExternalApiAsync(string instanceId)
{
string pipeline = @"[
{ ""$group"": {
""_id"": ""$Department"",
""employees"": { ""$push"": ""$CommonName"" }
}}
]";
// Get raw JSON from Keep
string json = await _keepClient.AggregateAsJsonAsync(
instanceId,
"CardholderInfo",
pipeline
);
// Send directly to external API
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
await _httpClient.PostAsync("https://analytics.example.com/import", content);
}
}
| Use Case | Recommended Method |
|---|---|
| Typed result objects | AggregateAsync<T> |
| Dynamic/unknown structure | AggregateAsJsonAsync |
| Logging raw responses | AggregateAsJsonAsync |
| Forwarding to other APIs | AggregateAsJsonAsync |
| Custom JSON parsing | AggregateAsJsonAsync |
💡 Raw JSON: Returns exactly what the server sends—no deserialization
💡 Performance: Slightly faster than typed aggregation (no object mapping)
⚠️ Parsing: You are responsible for parsing the JSON correctly
Example in C#
// Returns: IEnumerable<BsonDocument>
var bsonDocument = await client.AggregateAsync(FolderInfo folder, String collectionName, BsonDocument operations, Int32 queryTimeout, Boolean includeGlobal, String hints);
Run MongoDB aggregation pipelines against a collection. Returns BSON documents for complex data analysis, grouping, and transformation.
Task<IEnumerable<BsonDocument>> AggregateAsync(
FolderInfo folder,
string collection,
BsonDocument[] pipeline,
int queryTimeout = 600,
bool jsonStrict = false
)
| Parameter | Type | Description |
|---|---|---|
folder |
FolderInfo |
The folder context for the aggregation |
collection |
string |
MongoDB collection name (usually KeepObjects) |
pipeline |
BsonDocument[] |
Array of aggregation stages |
queryTimeout |
int |
Query timeout in seconds (default: 600) |
jsonStrict |
bool |
Use strict JSON mode |
// Count people by department
var pipeline = new BsonDocument[]
{
new BsonDocument("$match", new BsonDocument("_t", "Person")),
new BsonDocument("$group", new BsonDocument
{
["_id"] = "$Department",
["count"] = new BsonDocument("$sum", 1)
})
};
var results = await client.AggregateAsync(instance, "KeepObjects", pipeline);
foreach (var doc in results)
{
Console.WriteLine($"Department: {doc["_id"]}, Count: {doc["count"]}");
}
// Get controller online/offline counts
var pipeline = new BsonDocument[]
{
new BsonDocument("$match", new BsonDocument("_t", "Controller")),
new BsonDocument("$group", new BsonDocument
{
["_id"] = "$Status.IsOnline",
["count"] = new BsonDocument("$sum", 1)
})
};
var results = await client.AggregateAsync(instance, "KeepObjects", pipeline);
curl -X GET \
"https://api.acresecurity.cloud/api/f/{instance-key}/aggregate?queryTimeout=600&jsonStrict=false" \
-H "Authorization: Bearer TOKEN_GOES_HERE" \
-H "Content-Type: application/json" \
-d '[{"$match":{"_t":"Person"}},{"$group":{"_id":"$Department","count":{"$sum":1}}}]'
| Stage | Description | Example |
|---|---|---|
$match |
Filter documents | { "$match": { "_t": "Person" } } |
$group |
Group and aggregate | { "$group": { "_id": "$field", "count": { "$sum": 1 } } } |
$sort |
Sort results | { "$sort": { "count": -1 } } |
$limit |
Limit results | { "$limit": 10 } |
$project |
Shape output | { "$project": { "name": 1, "count": 1 } } |