Как использовать Addfields в MongoDB C # Aggregation Pipeline - PullRequest
0 голосов
/ 03 ноября 2018

В конвейере агрегации Mongo DB есть этап «AddFields», который позволяет проецировать новые поля в выходной документ конвейера, не зная, какие поля уже существовали.

Похоже, что он не был включен в драйвер C # для Mongo DB (используется версия 2.7).

Кто-нибудь знает, есть ли альтернативы этому? Может быть, флаг на этапе «Проект»?

Ответы [ 2 ]

0 голосов
/ 01 августа 2019

Я не уверен, что все использование 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 не поддерживается напрямую, и нам приходится прибегать к «волшебным струнам»

0 голосов
/ 23 января 2019

Как обсуждено здесь Используя $ addFields в MongoDB Driver для 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);
...