过滤器内部$eq不适用于数组字段 - Mongodb



我在下面有一个聚合查询。我将不得不过滤掉产品集合上的聚合结果,因为对于某些客户来说,有大量的产品,并且在没有过滤器的情况下获取所有客户的产品(在单个聚合查询中)将导致 Bson 太大的异常。问题是我想执行过滤器的字段之一是数组(p.metadata.category),Mongo $eg似乎不适用于数组字段,似乎它仅适用于简单的值和对象字段。

db.getCollection('customer').aggregate([
{
$lookup: {
from: 'Product',
localField: '_id',
foreignField: 'partiesList._id',
as: 'products',
}
},
{
$match: {
"_id": {$in: [
"C123",
"C456"
]
}
}
},
{
"$project": {
"products": {
"$filter": {
"input": "$products",
"as": "p",
"cond": {
$and:[
{
"$eq": ["$$p.metadata.category.name","somevalue"]
},
{
"$eq": ["$$p.isMain",true]
}
]
}
}
}
}
}
])

因此,上述查询的结果将是具有空产品数组的客户列表(尽管产品实际上存在),但是如果我从上面的查询中$and数组中删除metadata.category.name条件,它的工作方式就像魅力一样,p.isMain 过滤器工作正常并按预期过滤掉产品,仅显示 isMain 设置为 true 的产品。

这是我的示例数据:

客户:

{
"_id" : "C123",
"name" : "coooo"
}

产品 (客户的产品) :

{
"_id" : "PR123",
"isMain" : true,
"name" : "My Product",
"metadata" : {
"category" : [ 
{
"name" : "somevalue",
"version" : "1",
"referredType" : "Category",
"type" : "Category"
}, 
{
"name" : "someOtherValue",
"version" : "1",
"referredType" : "Category",
"type" : "Category"
}
]
},
"partiesList" : [ 
{
"_id" : "C123",
"role" : "Customer"
"referredType" : "Customer"
}
]
}

任何想法或替代方案??

由于Product.metadata.category是一个数组,因此"$$p.metadata.category.name"是每个元素中所有name值的数组。

然后,该$eq正在测试["somevalue", "someOtherValue"] == "somevalue"这总是错误的。

要检查数组中是否包含值,请使用$in,例如

{$in: ["somevalue", "$$p.metadata.category.name"]}

不相关的性能说明: 由于 match 语句考虑的是输入集合中文档的_id,因此将$match放在管道中$lookup之前将导致查找期间检索的文档更少,因此性能更快。