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

Posted

技术标签:

【中文标题】$eq 内部过滤器不适用于数组字段 - Mongodb【英文标题】:$eq inside filter does not work on array fields - Mongodb 【发布时间】:2021-10-07 04:58:11 【问题描述】:

我在下面有一个汇总查询。我必须过滤掉 Product 集合上的聚合结果,因为对于某些客户来说,有大量的产品,并且在没有过滤器的情况下(在单个聚合查询中)获取所有客户的产品会导致 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"
    
 ]

有什么想法或替代方案吗??

【问题讨论】:

语法看起来是对的,我们能看到一个它不工作的示例文档吗? @Joe,我更新了问题并放入了我的示例数据 【参考方案1】:

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

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

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

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

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

【讨论】:

以上是关于$eq 内部过滤器不适用于数组字段 - Mongodb的主要内容,如果未能解决你的问题,请参考以下文章

Logstash,grok 过滤器不适用于固定长度字段

MongoDriver c# 按日期字段中的月份名称过滤

打字稿类型检查不适用于数组过滤器

mongo 更新字段值,若不存在则自动创建

比较同一集合中的两个字段

NSPredicate 不适用于 ios 中的过滤