首页 > 解决方案 > Mongo DB 在多个嵌套数组的数组中查找值

问题描述

我需要检查非嵌套数组和多个嵌套数组中是否存在 ObjectId,我已经设法使用聚合框架非常接近,但在最后一步卡住了。

我的文件有这样的结构:

{
    "_id" : ObjectId("605ce5f063b1c2eb384c2b7f"),
    "name" : "Test",
    "attrs" : [ 
        ObjectId("6058e94c3994d04d28639616"), 
        ObjectId("6058e94c3994d04d28639627"), 
        ObjectId("6058e94c3994d04d28639622"), 
        ObjectId("6058e94c3994d04d2863962e")
    ],
    "variations" : [ 
        {
            "varName" : "Var1",
            "attrs" : [ 
                ObjectId("6058e94c3994d04d28639616"), 
                ObjectId("6058e94c3994d04d28639627"), 
                ObjectId("6058e94c3994d04d28639622"), 
                ObjectId("60591791d4d41d0a6817d23f")
            ],
        },
        {
            "varName" : "Var2",
            "attrs" : [ 
                ObjectId("60591791d4d41d0a6817d22a"), 
                ObjectId("60591791d4d41d0a6817d255"), 
                ObjectId("6058e94c3994d04d28639622"), 
                ObjectId("60591791d4d41d0a6817d23f")
            ],
        },
    ],
    "storeId" : "9acdq9zgke49pw85"
}

假设我需要检查这个 _id 是否存在"6058e94c3994d04d28639616"于所有名为attrs.

我的聚合查询是这样的:

db.product.aggregate([
      {
        $match: {
          storeId,
        },
      },
      {
        $project: {
          _id: 0,
          attrs: 1,
          'variations.attrs': 1,
        },
      },
      {
        $project: {
          attrs: 1,
          vars: '$variations.attrs',
        },
      },
      {
        $unwind: '$vars',
      },
      {
        $project: {
          attr: {
            $concatArrays: ['$vars', '$attrs'],
          },
        },
      },
    ]);

结果是:

  [
    {
      attr: [
        6058e94c3994d04d28639616,
        6058e94c3994d04d28639627,
        6058e94c3994d04d28639622,
        6058e94c3994d04d2863962e,
        6058e94c3994d04d28639616,
        6058e94c3994d04d28639627,
        6058e94c3994d04d28639622,
        60591791d4d41d0a6817d23f,
        60591791d4d41d0a6817d22a,
        60591791d4d41d0a6817d255,
        6058e94c3994d04d28639622,
        60591791d4d41d0a6817d23f
      ]
    },
    {
      attr: [
        60591791d4d41d0a6817d22a,
        60591791d4d41d0a6817d255,
        6058e94c3994d04d28639622,
        60591791d4d41d0a6817d23f,
        6058e94c3994d04d28639624,
        6058e94c3994d04d28639627,
        6058e94c3994d04d28639628,
        6058e94c3994d04d2863963e
      ]
    }
  ]

假设我的数据库中有两种产品,我会得到这个结果。最外层数组中的每个元素都是不同的产品。

最后一点,即检查这个键"6058e94c3994d04d28639616",我找不到方法来做$group,因为我没有键来分组。或者使用$match,将其添加到聚合的末尾:

  {
    $match: {
      attr: "6058e94c3994d04d28639616",
    },
  },

但这会导致一个空数组。我知道它$match不会像这样查询数组,但也找不到这样做的方法$in

这是否过于复杂的架构?我不能嵌入原始数据,因为它是可变的,如果发生变化,我不乐意更改所有产品。

如果我有 10000 个产品,这会很贵吗?

提前致谢

标签: arraysmongodbaggregation-framework

解决方案


您正在尝试将字符串6058e94c3994d04d28639616与 ObjectId 进行比较。$toObjectId执行如下操作时,使用运算符将​​字符串转换为 ObjectId $match

    {
        $match: {
            $expr: {
                $in: [{ $toObjectId: "6058e94c3994d04d28639616" }, "$attr"]
            }
        }
    }

推荐阅读