【问题标题】:MongoDB: How do I delete nested object by index?MongoDB:如何按索引删除嵌套对象?
【发布时间】:2021-11-09 03:26:19
【问题描述】:

所以我想做一个删除回复系统,但我不知道怎么做。你能帮帮我吗? 这是我的桌子 image of my mongodb

我尝试过的代码是,但它不起作用

app.post("/remove-reply", async (req, res) => {
const index = parseInt(req.body.index) - 1

await Posts.findOneAndUpdate({ _id: req.body.id }, [
    {
        $set: {
            "Comments.$[].replies": {
                $concatArrays: [
                    { $slice: ["$Comments.$[].replies", index] },
                    { $slice: ["$Comments.$[].replies", { $add: [1, index] }, { $size: "$Comments.$[].replies" }] }
                ]
            }
        }
    }
])
res.redirect("/")
})

它给了我这个错误

    (node:17376) UnhandledPromiseRejectionWarning: MongoServerError: Invalid $set :: caused by :: FieldPath field names may not start with '$'.
    at MessageStream.messageHandler (C:\Users\The.Peerapon\Desktop\programming\Express-app\node_modules\mongodb\lib\cmap\connection.js:467:30)
    at MessageStream.emit (events.js:400:28)
    at processIncomingData (C:\Users\The.Peerapon\Desktop\programming\Express-app\node_modules\mongodb\lib\cmap\message_stream.js:108:16)
    at MessageStream._write (C:\Users\The.Peerapon\Desktop\programming\Express-app\node_modules\mongodb\lib\cmap\message_stream.js:28:9)
    at writeOrBuffer (internal/streams/writable.js:358:12)
    at MessageStream.Writable.write (internal/streams/writable.js:303:10)
    at TLSSocket.ondata (internal/streams/readable.js:731:22)
    at TLSSocket.emit (events.js:400:28)
    at addChunk (internal/streams/readable.js:293:12)
    at readableAddChunk (internal/streams/readable.js:267:9)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:17376) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:17376) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

我的目标是在回复时单击删除按钮以按索引将其删除。

【问题讨论】:

  • 已编辑请帮忙
  • 现在好多了。如果您可以包含示例数据集和预期输出,那就更好了:) Mongoplayground 是共享 mongodb 可重现示例的便捷工具之一。
  • 我的预期输出是通过索引删除帖子中评论中的回复
  • 我认为我们仍然需要一些澄清,因为Comments 也是一个数组。你的意思是会给你2个索引,一个给Comments,一个给replies,这样你就可以通过Comments.x.replies.y删除replies中的元素?正如我所说,具体的预期输出将有助于社区了解需求。

标签: javascript html mongodb


【解决方案1】:

对于每个评论\回复,将其索引保存在数据库中并将其用作一种 id。然后,当有人想删除评论时,您可以执行以下操作:

app
  .post('/remove-reply', async (req, res) => {
    const postId = req.body.id;
    const commentIndex = parseInt(req.body.commentIndex) - 1;
    const replyId = req.body.replyIndex;
    await Posts.findOneAndUpdate({
      _id: postId
    }, {
      $pull: {
        [`Comments.${ commentIndex }.replies`]: {
          _id: replyId 
        }
      }
    });
    res.redirect('/');

  });

因此,当用户单击要删除的回复时,您应该拥有查找要删除的确切回复所需的全部 3 个字段。

您也可以为每个项目保存一个自动生成的唯一 id 以用作标识符\索引,因为在此用例中我们将其视为集合而不是数组。它可能会更容易维护,因为删除评论后,索引不再与底层数组对齐。

【讨论】:

  • 谢谢!这工作正常,但你的代码一开始不正确,但我已经修复你的代码工作
  • @UltimateSheepConfusedAtCode 如果您愿意,您可以在网站上编辑我的答案并将其更改为适合您的答案。这将帮助人们在未来查看此问题+答案以了解解决此问题的方法
猜你喜欢
  • 2022-06-13
  • 1970-01-01
  • 1970-01-01
  • 2021-04-11
  • 1970-01-01
  • 2018-04-26
  • 2021-07-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多