【问题标题】:Mongo DB find value in array of multiple nested arraysMongodb在多个嵌套数组的数组中查找值
【发布时间】:2021-03-25 22:08:16
【问题描述】:

我需要检查非嵌套数组和多个嵌套数组中是否存在 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 是否存在于所有名为 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 件产品,这会很贵吗?

提前致谢

【问题讨论】:

  • _id 匹配时,您期望的输出格式是什么?
  • 此外,查询不会在您的问题中产生“结果”。
  • 我期待任何能让我检查密钥是否存在的东西。这个查询的产生与我发布的完全一样,我只是复制粘贴它。

标签: arrays mongodb aggregation-framework


【解决方案1】:

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

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

【讨论】:

  • 是的!我不包括$expr ,这使它起作用了!非常感谢!
猜你喜欢
  • 1970-01-01
  • 2022-11-11
  • 2015-06-20
  • 2023-02-01
  • 2015-05-18
  • 1970-01-01
  • 2020-12-18
  • 2017-09-30
  • 2021-08-27
相关资源
最近更新 更多