【问题标题】:How to use Addfields in MongoDB C# Aggregation Pipeline如何在 MongoDB C# 聚合管道中使用 Addfields
【发布时间】:2019-04-07 13:16:33
【问题描述】:

Mongo DB 的聚合管道有一个“AddFields”阶段,允许您将新字段投影到管道的输出文档中,而无需知道哪些字段已经存在。

Mongo DB(使用 2.7 版)的 C# 驱动程序中似乎没有包含此功能。

有谁知道是否有任何替代方案?也许是“项目”阶段的一面旗帜?

【问题讨论】:

  • jira.mongodb.org/browse/CSHARP-1750。阅读“无法解决”的决议。给出了理由,但显然根本不在路线图上。如果您真的想要它,请使用 BsonDocument 构建器手动指定管道,因为这就是所有 API 方法实际上都在做的事情。和/或投票支持 JIRA 问题,如果有足够的支持,那么也许有人会认为它值得在未来的工作中考虑。

标签: c# mongodb aggregation


【解决方案1】:

我不确定是否需要所有 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 不被直接支持,我们不得不求助于“魔术字符串”

【讨论】:

    【解决方案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);
    

    【讨论】:

      猜你喜欢
      • 2021-08-04
      • 1970-01-01
      • 2020-12-30
      • 1970-01-01
      • 2014-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多