Mongo Queries - C# Driver
Writing Complex Mongo Queries using Aggregation - Builders and BsonDocuments
Builders -
1
2
3
4
5
6
7
8
9
10
11
12
| //Filter Definition Builder
var builder = Builders<T>.Filter;
var filter = builder.Ne(_=>_.{field}, true);
filter = filter & builder.Eq(_=>_.{field}, value);
filter = filter & builder.Gte(_=>_.{field}, value);
filter = filter & builder.Lte(_=>_.{field}, value);
filter = filter & builder.In(_=>_.{field}, value);
filter = filter & builder.In(_=>_.{field}, new List<string> { value1, value2});
filter = filter & builder.AnyEq(_=>_.{field}, value);
filter = filter & builder.Or(_=>_.{field}, value);
filter = filter & builder.And(_=>_.{field}, value);
filter = filter & builder.ElemMatch(_=>_.{field}, t => t.Id == Id, t.Key == Key);
|
1
2
3
4
5
6
7
8
9
| //Sort Definition Builder
var sortfilter = Builders<T>.Sort.Descending(_=>_.{field});
//Update Definition Builder
UpdateDefinition<T> updateDef = Builders<T>.Update.Set(_=>_.{Field1}, value);
update = ({Field2} != null) ? updateDef.Set(_=>_.{Field3}, value) : updateDef;
//Projection Definition Builder
var projection = Builders<BsonDocument>.Projection.Include("x").Include("y").Exclude("_id");
|
BsonDocument -
Building mongo Queries that have complex conditions and search criteria can be appended by checking If/else conditions
1
2
3
4
5
6
7
8
9
10
11
12
| //Match
var match = new BsonDocument(true); //true is to allow duplicate keys to be added to the Bson Document
match.Add("{field}", new BsonDocument{ { "$ne" , value }} );
match.Add("{field}", new BsonDocument{ { "$eq" , value }} );
match.Add("{field}", new BsonDocument{ { "$lt" , value }} );
match.Add("{field}", new BsonDocument{ { "$gt" , value }} );
match.Add("{field}", new BsonDocument{ { "$in" , new BsonArray(values) }} );
match.Add("{field}", new BsonDocument{ { "$nin" , new BsonArray(values) }} );
match.Add("{field}", new BsonDocument{ { "$gte" , dateRangeStart }, { "$lte" , dateRangeEnd }} );
match.Add("{field}", new BsonDocument{ { "$gte" , date }} );
match.Add("{field}", new BsonArray() { new BsonDocument {{ "{field", value} , {"{field2", value }}} );
match.Add("{field}", new BsonDocument{ { "$elemMatch" , newBsonDocument {{ "{field}", value}, {"{field2", value }} }} );
|
1
2
3
4
| //Sort
var sort = new BsonDocument();
sort.Add(new BsonDocument("{field}", 1)); //Ascending
sort.Add(new BsonDocument("{field}", -1)); //Descending
|
Building Mongo Queries that don't have complex conditions
//Building Mongo Queries that are not too complex
private BsonDocument[] BuildPipeline()
{
var match = new BsonDocument
{
{
"$match", new BsonDocument { {"field", value},
{"field", value},
{"field", new BsonDocument() { { "$in", new BsonArray(values)}}},
{ "field" , new BsonDocument { { "$elemMatch" , new BsonDocument { { "field", value }}}}}};
}
};
var lookup = new BsonDocument
{
{
"$lookup", new BsonDocument { { "from", "field"}, {"localField", "field"}, {"foreignField", "field"}, { "as", "field"}}
}
};
var sort = new BsonDocument{
{
"$sort" , new BsonDocument{ { "field", -1 } }
}
};
var limit = new BsonDocument{
{
"$limit" , limit }
}
};
var group = new BsonDocument
{
{
"$group", new BsonDocument
{
{ "_id", "groupbyfield"},
{"id", new BsonDocument() { { "$first", "field"}}},
{"title", new BsonDocument() { { "$first", "field"}}},
{"desc", new BsonDocument() { { "$first", "field"}}},
{"objects", new BsonDocument() { { "$push", "$$ROOT"}}},
}
}
};
var project = new BsonDocument{
{
"$project" , new BsonDocument{ { "field", 0 } }
}
};
var unwind = = new BsonDocument{
{
"$unwind" , "field" }
}
};
BsonDocument[] pipe = new[] { match, lookup, sort, limit, group, project, unwind };
return pipeline;
}
Building Pipeline for Aggregation Call -
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| //Pipeline Builder using Builders
var pipe = new EmptyPipelineDefinition<T>()
.Match(filter)
.Project(project)
.Sort(sort)
.Limit(limit)
var aggregate = await Aggregate(pipe).ConfigureAwait(false);
var result = { aggregate.ToList(), aggregate.Count() };
//Pipeline Query to get total Count of documents
var pipe = new EmptyPipelineDefinition<T>()
.Match(match)
.Project(new BsonDocument("id", 1)) //The idea is to project only one field so that Count() performance is increased
.Count();
var aggregate = await Aggregate(pipe).ConfigureAwait(false);
return (aggregate.count() == 0) ? 0 : aggregate.First().Count;
|
Comments
Post a Comment