如何在MongoDB C#聚合管道中使用Addfields

时间:2018-11-03 16:03:25

标签: c# mongodb aggregation

Mongo DB的Aggregation管道具有一个“ AddFields”阶段,该阶段使您可以将新字段投影到管道的输出文档中,而无需知道已经存在哪些字段。

似乎这未包含在Mongo DB的C#驱动程序中(使用2.7版)。

有人知道这是否有其他选择吗?也许是“项目”阶段的标志?

2 个答案:

答案 0 :(得分:2)

如此处Using $addFields in MongoDB Driver for C#所述,您可以使用BsonDocument自己构建聚合阶段。

要使用https://docs.mongodb.com/manual/reference/operator/aggregation/addFields/

中的示例
{
  $addFields: {
    totalHomework: { $sum: "$homework" } ,
    totalQuiz: { $sum: "$quiz" }
  }
}

看起来像这样:

BsonDocument expression = new BsonDocument(new List<BsonElement>() {
    new BsonElement("totalHomeWork", new BsonDocument(new BsonElement("$sum", "$homework"))),
    new BsonElement("totalQuiz", new BsonDocument(new BsonElement("$sum", "$quiz")))
});
BsonDocument addFieldsStage = new BsonDocument(new BsonElement("$addFields", expression));
IAggregateFluent<BsonDocument> aggregate = col.Aggregate().AppendStage(addFieldsStage);

表达式是代表BsonDocument的

{
  totalHomework: { $sum: "$homework" } ,
  totalQuiz: { $sum: "$quiz" }
}

您可以像往常一样将其他阶段附加到IAggregateFluent对象上

IAggregateFluent<BsonDocument> aggregate = col.Aggregate()
    .Match(filterDefintion)
    .AppendStage(addFieldsStage)
    .Project(projectionDefintion);

答案 1 :(得分:0)

我不确定是否需要使用所有BsonDocument。当然,在此示例中,我没有将文本搜索的textScore附加到搜索结果中。

        private IAggregateFluent<ProductTypeSearchResult> CreateSearchQuery(string query)
        {
            FilterDefinition<ProductType> filter = Builders<ProductType>.Filter.Text(query);
            return _collection
                .Aggregate()
                .Match(filter)
                .AppendStage<ProductType>("{$addFields: {score: {$meta:'textScore'}}}")
                .Sort(Sort)
                .Project(pt => new ProductTypeSearchResult
                {
                    Description = pt.ExternalProductTypeDescription,
                    Id = pt.Id,
                    Name = pt.Name,
                    ProductFamilyId = pt.ProductFamilyId,
                    Url = !string.IsNullOrEmpty(pt.ShopUrl) ? pt.ShopUrl : pt.TypeUrl,
                    Score = pt.Score
                });
        }

请注意,ProductType确实具有一个定义为

Score属性
        [BsonIgnoreIfNull]
        public double Score { get; set; }

不幸的是,$addFields没有得到直接支持,我们不得不求助于“魔术字符串”