如何通过查询子文档将数组用作过滤器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何通过查询子文档将数组用作过滤器相关的知识,希望对你有一定的参考价值。

我的mongodb集合上有以下文档结构:

{
"_id" : "5Ci9sLeBu2iPbWtR5",
"productId" : "010101111",
"description" : "PRODUCT EXAMPLE REF 1001",
"prices" : [ 
    {
        "priceId" : 10,
        "description" : "Promotions",
        "price" : 97.99
    },
    {
        "priceId" : 15,
        "description" : "Retail list",
        "price" : 105.65
    },
    {
        "priceId" : 20,
        "description" : "Standard list",
        "price" : 109.10
    }
]}

我想要的只是查询priceIds的特定数组,例如:[10,20],结果:

{
"_id" : "5Ci9sLeBu2iPbWtR5",
"productId" : "010101111",
"description" : "PRODUCT EXAMPLE REF 1001",
"prices" : [ 
    {
        "priceId" : 10,
        "description" : "Promotions",
        "price" : 97.99
    },
    {
        "priceId" : 20,
        "description" : "Standard list",
        "price" : 109.10
    }
]}

使用带有$ filter的$ in运算符(完美的虚构场景):

db.getCollection('products').aggregate([
{$match: { "productId":"010101111" }},
{$project: { 
    "prices": {
        $filter: {
            input: "$prices",
            as: "price",
            cond: { $in: ["$$price.priceId",[10, 20]] }
        }
    }
}}])

它不起作用,因为mongodb抱怨$ in运算符(“无效运算符'$ in'”)。

当然,我可以通过$ unwind来做到这一点,但我会遇到性能问题,因为毕竟我需要再次组合。

我在问题中找到的最接近的答案是这两个:

  1. Retrieve only the queried element in an object array in MongoDB collection
  2. Filter array using the $in operator in the $project stage

但它们都没有关于在子文档中使用数组过滤器进行搜索。

答案

$in运算符仅在MongoDB 3.4+的聚合管道中有效。但是,解决方法涉及使用集合运算符。使用$setIsSubset作为替换,如果第一组的所有元素都出现在第二组中,则返回true,包括第一组等于第二组时:

cond: { $setIsSubset: [["$$price.priceId"],[10, 20]] }

以上是关于如何通过查询子文档将数组用作过滤器的主要内容,如果未能解决你的问题,请参考以下文章

通过扩展方法过滤子查询

在 Mongoose/MongoDB 的文档中过滤数组、子文档、数组、文档

如何使用 Mongoose 查询过滤到数组类型字段中具有指定值的文档?

如何使用MongoDB过滤子文档中的数组[重复]

通过 Id 查找文档并在 Mongoose 中过滤子数组

查询子文档并从中选择过滤后的数据 Mongoose