如何使用mongoDb中的.net驱动程序聚合和替换数据?

时间:2018-03-20 13:57:24

标签: c# .net mongodb

我遇到mongodb查找问题。以下是如何重现我的问题的基本示例

public class Product
{
    public string Id { get; set; }    
    public string Name { get; set; }
    public double Price { get; set; }
}

public class OrderProduct
{
    public string ProductId { get; set; }
    public int Quantity { get; set; }
}

public class Order
{
    public string Id { get; set; }
    public List<OrderProduct> OrderProducts { get; set; }
    public double Total { get; set; }
}

我想获得订单和所有相关产品。 所以这是我的查询

 var filter = Builders<Entities.Order>.Filter.Eq(x => x.Id, id);
        var result = await Collection.Aggregate()
            .Match(filter)
            .Lookup("Product", "OrderProducts.ProductId", "_id", "Products")
            .FirstOrDefaultAsync();

所以基本上我成功地从集合中获取数据,但格式有点不同。我正在收到BsonDocument

{
   { 
      "_id":"5ab0c1ec36e4e937302ee1df",
      "Total":225,
      "OrderProducts":
       [
          {
             "ProductId":"5ab0c1dc36e4e937302ee1de",
             "Quantity":2
          }
       ],
       Products:
       [
          {
              "_id":"5ab0c1dc36e4e937302ee1de",
              "Name":"Test product",
              "Price":20
          }
       ]
    }

但我想得到这样的文件:

{
   { 
      "_id":"5ab0c1ec36e4e937302ee1df",
      "Total":225,
      "OrderProducts":
       [
          {
             "_id":"5ab0c1dc36e4e937302ee1de",
              "Name":"Test product",
              "Price":20,
             "Quantity":2
          }
       ]           
    }

您对如何实现这一点有什么想法吗?我找到了运算符mergeObject但我不知道如何在这里添加它。还有一个:是否有更优雅的方式来指定查找?这里没有硬编码的字符串.Lookup("Product", "OrderProducts.ProductId", "_id", "Products")

1 个答案:

答案 0 :(得分:0)

为避免硬编码字符串,您可以使用nameof运算符。要获得所需的形状,您需要摆脱数组(使用Unwind),然后使用Lookup,然后分组回单Order

尝试:

    var filter = Builders<Order>.Filter.Eq(x => x.Id, id);
    var result = Collection.Aggregate<Order>()
        .Match(filter)
        .Unwind(a => a.OrderProducts)
        .Lookup(nameof(Product), $"{nameof(Order.OrderProducts)}.{nameof(OrderProduct.ProductId)}", "_id", nameof(Product))
        .Unwind(nameof(Product))
        .Group(new BsonDocument
          {
               { "_id", "_id" },
               { nameof(Order.Total) , new BsonDocument("$first", $"${nameof(Order.Total)}")},
               { nameof(Order.OrderProducts),
                    new BsonDocument("$push",
                        new BsonDocument() {
                            { "_id", $"${nameof(Product)}._id" },
                            { nameof(Product.Name), $"${nameof(Product)}.{nameof(Product.Name)}" },
                            { nameof(Product.Price), $"${nameof(Product)}.{nameof(Product.Price)}" },
                            { nameof(OrderProduct.Quantity), $"${nameof(OrderProduct)}s.{nameof(OrderProduct.Quantity)}" }
                        }
               )},
          })
        .FirstOrDefault();