使用elemMatch时如何从投影中排除元素?Mongo C#驱动程序

3
我有一个名为“Trades”的集合。这是集合的结构:
{
 "TradeId": 1234,
 "Products": [
  {
     "Name": "Test product",
     "Offers": [
        {
           "SupplierName": "John Smith",
           "OfferPrice": 12345.6
        }],
     "Requests": [
        {
           "CustomerName": "Anna Doe",
           "RequestPrice": 28574.5
        }]
   }]
}

我需要获取指定交易的"Offers"数组,同时按产品名称进行过滤。以下是我目前所做的:

            var filteredTrade = await _tradesCollection.Find(
                        x => x.TradeId == 1234)
                    .Project<Trade>(Builders<Trade>.Projection.ElemMatch(
                        x => x.Products,
                        i => i.Name == "Test product"))
                    .SingleOrDefaultAsync();

这按照产品名称过滤,与预期相符。但是查询还会获取整个请求集合。是否有任何方法可以仅获取报价集合或以某种方式排除请求集合?

1个回答

1
你需要使用聚合框架来投影一个具有多层嵌套数组的文档。在mongo shell中,你可以尝试以下代码:
db.col.aggregate([
    {
        $match: { TradeId: 1234 }
    },
    {
        $unwind: "$Products"
    },
    {
        $match: { "Products.Name": "Test product" }
    },
    {
        $project: {
            _id: 0,
            Offers: "$Products.Offers"
        }
    }
])

输出: { "Offers" : [ { "SupplierName" : "John Smith", "OfferPrice" : 12345.6 } ] }

可以翻译为以下的C#代码(返回类型为Product的列表):

var project = new BsonDocumentProjectionDefinition<BsonDocument>(
    BsonDocument.Parse("{ Offers: \"$Products.Offers\", _id: 0 }"));

var q = Col.Aggregate()
            .Match(x => x.TradeId == 1234)
            .Unwind<Trade>(x => x.Products)
            .Match(x => x["Products.Name"] == "Test product")
            .Project(project)
            .As<Product>()
            .ToList();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接