I know that this is not a feature and will not be implemented as stated here: https://jira.mongodb.org/browse/CSHARP-1750
However I really need to execute an aggregation with the $addFields operator. According to the comment on How to use Addfields in MongoDB C# Aggregation Pipeline
jira.mongodb.org/browse/CSHARP-1750. Read the resolution "won't fix". The reasoning is given, but it's clearly not on the roadmap at all. If you really want it then specify the pipeline manually with BsonDocument builders since that's all the API methods actually do anyway. And/Or vote up the JIRA issue, and with sufficient backing then maybe someone will think it worth considering for future work. – Neil Lunn Nov 3 '18
you can manually build the pipeline. How would I go about doing that, and can I use the aggregation I have before, and possibly after the manual string, so I don't have to build the entire thing by hand but only the addFields part?
I have tried
StringBuilder addFieldsDefinition = new StringBuilder();
addFieldsDefinition.AppendLine("{");
addFieldsDefinition.AppendLine("\"values"":{$reduce: {");
addFieldsDefinition.AppendLine("input: \"$values\",");
addFieldsDefinition.AppendLine("initialValue: {timeStamp: ISODate(\"0000-01-01T00:00:00.000+0000\")},");
addFieldsDefinition.AppendLine("in: {$cond: [{$and : [");
addFieldsDefinition.AppendLine("{$gte : [\"$$this.timeStamp\", \"$$value.timeStamp\"]},");
addFieldsDefinition.AppendLine("{$lte : [\"$$this.timeStamp\", ISODate(\"" + dt.ToString("yyyy-MM-dd") + "T" + dt.ToString("HH:mm:ss.fff") + "\")]}");
addFieldsDefinition.AppendLine("]}, \"$$this"", \"$$value\"]}");
addFieldsDefinition.AppendLine("}}");
addFieldsDefinition.AppendLine("}");
IAggregateFluent<BsonDocument> aggregate = col.Aggregate()
.Match(filterDef)
.Project(projectDef);
aggregate.Stages.Add("$addFields : " + addFieldsDefinition .ToString());
Wanting to get the Element in an Array where the 'timeStamp' field in the sub-document is the highest but under a specified dateTime. But the Code tosses me an Exception when I try to add the stage, saying a String can't be converted into an IPipelineStageDefinition.
I do not want to do the built in Aggregations like so (pseudocode)
.Unwind(values).Match(timestamp < dt).Sort(timeStamp).Limit(1)
because that's super slow.
Edit:
I now use the MongoDB.Bson Objects to create the stage: VB.NET Code (Sorry but I can't be bothered to convert that mess by hand)
Dim stage As New BsonDocument(New BsonElement("$addFields", New BsonDocument(New BsonElement("value",
New BsonDocument(New BsonElement("$reduce", New BsonDocument(New List(Of BsonElement) From
{
New BsonElement("input", New BsonString("$" + FieldNames.VALUES_FIELDNAME)),
New BsonElement("initialValue", New BsonDocument(New BsonElement("timeStamp", New BsonDateTime(DateTime.MaxValue)))),
New BsonElement("in", New BsonDocument(New List(Of BsonElement) From
{
New BsonElement("$cond", New BsonArray() From
{
New BsonDocument(New BsonElement("$and", New BsonArray() From
{
New BsonDocument(New BsonElement("$lte", New BsonArray() From {New BsonString("$$this.timeStamp"), New BsonString("$$value.timeStamp")})),
New BsonDocument(New BsonElement("$gte", New BsonArray() From {New BsonString("$$this.timeStamp"), New BsonDateTime(dt)}))
})),
New BsonString("$$this"),
New BsonString("$$value")
})
}
))
}
))))
)))