【问题标题】:MongoDB (Mongoose) - Get only records where nested item is equal to a valueMongoDB (Mongoose) - 仅获取嵌套项等于值的记录
【发布时间】:2021-12-14 14:16:17
【问题描述】:

我搜索了很多,尝试了几种方法,但没有任何效果。

我在 mongo 中有这个:

{
    id: ObjectId("1234567890"),
    answers: [{
        id: 111,
        deleted:0
    },
    {
        id: 222,
        deleted:0
    },
    {
        id: 333,
        deleted:1
    }]
},
{
    id: ObjectId("0987654321"),
    answers: [{
        id: 111,
        deleted:0
    },
    {
        id: 222,
        deleted:1
    },
    {
        id: 333,
        deleted:1
    }]
}

我想要带有 ObjectId("1234567890") 的文档,并且只有带有 delete = 1 的答案(只有 id 333)。

我试过这个:

  var query = chatbotMongoModel.find(
                { _id: "1234567890" },
                { answers: {$elemMatch: {deleted: "1"}}}
            )

但返回所有答案..你能给我一些帮助吗?

谢谢!

拉斐尔

【问题讨论】:

  • 您能否编辑您的帖子以使您的脚本与您的示例数据相对应?我认为 id 6166e7ef89b9f3d92b764fb4 匹配 1234567890fluxoanswers 相同。
  • 对不起,我改了!
  • 如果您在 MongoDB 中运行相同的参数 { _id: "1234567890" }, { answers: {$elemMatch: {deleted: "1"}}} 或使用像 Robot3 这样的 MongoDB 客户端,您会得到预期的结果吗?

标签: node.js mongodb mongoose aggregation-framework


【解决方案1】:

一种方法是使用 mongodb 聚合框架。

var result = await chatbotMongoModel.aggregate([
  {
    $match: {
      id: "1234567890"
    }
  },
  {
    "$unwind": {
      path: "$answers"
    }
  },
  {
    $match: {
      "answers.deleted": 1
    }
  },
  {
    $group: {
      _id: "$id",
      answers: {
        $push: "$answers"
      },
      allFields: {
        $first: "$$ROOT"
      }
    }
  },
  {
    "$replaceRoot": {
      "newRoot": {
        "$mergeObjects": [
          "$allFields",
          {
            "answers": "$answers"
          }
        ]
      }
    }
  }
])

请注意,在您的示例文档中,您有 id,但您在查询中使用了 _id,它们必须匹配。 deleted 数据类型在示例文档中也是数字,但您在查询中使用字符串值。

正在运行mongoplayground

另一种替代解决方案:

var result = await chatbotMongoModel.aggregate([
  {
    $match: {
      id: "1234567890"
    }
  },
  {
    $addFields: {
      "answers": {
        $filter: {
          input: "$answers",
          as: "answer",
          cond: {
            $eq: [
              "$$answer.deleted",
              1
            ]
          }
        }
      }
    }
  }
])

mongoplayground

【讨论】:

  • 感谢@SuleymanSah,我在 mongoplayground 中看到了..它可以工作..但是在我的带有 mongoose 的 nodejs 应用程序中,没有返回任何内容... ;(
  • 你给我的第一个解决方案返回错误“不支持聚合项目运算符:'$mergeObjects'”,第二个没有返回任何内容..
  • @RafaelSpessotto mergeObject 需要 mongodb 3.6 版。看来你的版本低于 3.6。 addFields 的第二个解决方案应该返回文档,我想你需要像这样调整匹配查询'_id': mongoose.Types.ObjectId("...") 。请尝试。您的解决方案几乎相同。
【解决方案2】:

感谢您的回答!我找到了一个解决方案,如果有人也需要这个,我会在这里发布......

var query = model.aggregate([
        { $match: { '_id': mongoose.Types.ObjectId("1234567890") } },
        {
          $project: {
            answer: {
              $filter: {
                input: "$answer",
                as: "f",
                cond: { $eq: ["$$f.deleted", 1] }
              }
            }
          }
        }
      ])

问候!

【讨论】:

    猜你喜欢
    • 2015-10-30
    • 1970-01-01
    • 2011-11-10
    • 1970-01-01
    • 1970-01-01
    • 2020-08-15
    • 2016-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多