代码之家  ›  专栏  ›  技术社区  ›  Code_Worm

$eq内部过滤器对数组字段不起作用-Mongodb

  •  0
  • Code_Worm  · 技术社区  · 4 年前

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

    所以,上述查询的结果将是产品数组为空的客户列表(尽管产品实际上存在),但如果我删除 metadata.category.name 在上面的查询中,来自$和数组的条件像charm一样工作,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"
        }
     ]
    }
    

    有什么想法或选择吗??

    0 回复  |  直到 4 年前
        1
  •  1
  •   Joe    4 年前

    自从 Product.metadata.category 是一个数组, "$$p.metadata.category.name" 是所有 name 每个元素中的值。

    那个 $eq 然后是测试 ["somevalue", "someOtherValue"] == "somevalue" 这永远都是假的。

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

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

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