考虑以下集合:
{
"_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"
)
)
);
这似乎也不起作用。
谢谢你。
您可以展开数组并执行 $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")
})))
}