如何创建一个过滤器,将嵌套值与 mongodb 中父集合的值相匹配?

问题描述 投票:0回答:1

考虑以下集合:

{
   "_id" : (guid),
   "basePrice" : 5000,
   "productCategories" : [{
       "_id" : (Guid),
       "categoryName" : "",
       "isActive" : true,
       "products" : [{
           "_id" : (guid),
           "productCode" : "GoKart",
           "price" : 5000
       }]
   }]
}

我正在尝试获取一个集合,其中 basePrice == ProductCategory 处于活动状态的价格。

我尝试了下面的c#代码:

.Where(
   x => x.ProductCategories.Any(pc =>
               pc.IsActive &&
               pc.Products.Any(p =>
                    p.Type.ShortCode == "GoKart" &&
                    p.Price == x.BasePrice
               )
    )
)

虽然代码看起来没问题,但这似乎不受 MongoDB 支持。

然后我尝试使用生成器查询。但是在使用 ElemMatch 时,我无法使用过滤器属性内的字段属性。

我觉得我的做法完全错误。 由于比较是在文档内,因此我们遇到了这个问题。是否可以将集合中的值作为过滤器进行比较并获取文档?我不想将其存入内存,因为记录非常大。

我最近尝试过以下代码:

filterBuilder.And(                                
   Builders<Inventory>.Filter.ElemMatch(inv => inv.ProductCategorys,                                    
      Builders<ProductCategory>.Filter.And(                                        
         Builders<ProductCategory>.Filter.Eq(pc => pc.IsActive, true),                                        
         Builders<ProductCategory>.Filter.ElemMatch(pc => pc.Products,                                            
            Builders<Product>.Filter.Eq(p => p.ShortCode, "GoKart")
         )
      )
   ),
   Builders<Inventory>.Filter.Eq("$expr",
      Builders<Inventory>.Filter.Eq(
         "$basePrice" ,                                        
         "$ProductCategories.Products.Price"
      )
   )
);   

这似乎也不起作用。

谢谢你。

c# mongodb mongodb-query
1个回答
0
投票

您可以展开数组并执行 $match 来检查相等性,然后使用 mongo 聚合将它们分组。 像这样的东西:

[{
$match: {
  "productCategories.isActive": true,
},},{ $unwind: {
  path: "$productCategories",
  preserveNullAndEmptyArrays: true,
},},{
$unwind: {
  path: "$productCategories.products",
  preserveNullAndEmptyArrays: true,
}, }, {
$match: {
  $expr: {
    $eq: [
      "$basePrice",
      "$productCategories.products.price",
    ],
  },
},},{
$group: {
  _id: "$productCategories.products._id",
  products: {
    $push: "$productCategories.products",
  },
  doc: {
    $first: "$$ROOT",
  },
}, }, { $replaceRoot: {
  newRoot: {
    $mergeObjects: [
      {
        products2: "$products",
      },
      "$doc",
 ],
  },
},}, {
$set: {
  "productCategories.products": "$products2",
},},{
$unset: "products2",}, { $group: {
  _id: "$productCategories._id",
  detail: {
    $first: "$$ROOT",
  },
  productCategories: {
    $addToSet: "$productCategories",
  },
},},  {    $replaceRoot: {
  newRoot: {
    $mergeObjects: [
      "$detail",
      {
        productCategories:
          "$productCategories",
      },
    ],
  },
},},]

示例 C# 代码如下所示:

new BsonArray{
new BsonDocument("$match", 
new BsonDocument("productCategories.isActive", true)),
new BsonDocument("$unwind", 
new BsonDocument
    {
        { "path", "$productCategories" }, 
        { "preserveNullAndEmptyArrays", true }
    }),
new BsonDocument("$unwind", 
new BsonDocument
    {
        { "path", "$productCategories.products" }, 
        { "preserveNullAndEmptyArrays", true }
    }),
new BsonDocument("$match", 
new BsonDocument("$expr", 
new BsonDocument("$eq", 
new BsonArray
            {
                "$basePrice",
                "$productCategories.products.price"
            }))),
new BsonDocument("$group", 
new BsonDocument
    {
        { "_id", "$productCategories.products._id" }, 
        { "products", 
new BsonDocument("$push", "$productCategories.products") }, 
        { "doc", 
new BsonDocument("$first", "$$ROOT") }
    }),
new BsonDocument("$replaceRoot", 
new BsonDocument("newRoot", 
new BsonDocument("$mergeObjects", 
new BsonArray
            {
                new BsonDocument("products2", "$products"),
                "$doc"
            }))),
new BsonDocument("$set", 
new BsonDocument("productCategories.products", "$products2")),
new BsonDocument("$unset", "products2"),
new BsonDocument("$group", 
new BsonDocument
    {
        { "_id", "$productCategories._id" }, 
        { "detail", 
new BsonDocument("$first", "$$ROOT") }, 
        { "productCategories", 
new BsonDocument("$addToSet", "$productCategories") }
    }),
new BsonDocument("$replaceRoot", 
new BsonDocument("newRoot", 
new BsonDocument("$mergeObjects", 
new BsonArray
            {
                "$detail",
                new BsonDocument("productCategories", "$productCategories")
            })))

}

Mongo 游乐场:https://mongoplayground.net/p/uZDZfyz7tur

© www.soinside.com 2019 - 2024. All rights reserved.