Haz*_*ldo 2 mongoose mongodb node.js express
我的 Mongoose 代码位于单独的model.js文件中,而用于处理 http 请求的 Express 代码位于app.js. 我只是在为一个虚构的 wiki 文章网站练习创建 API 并在 Postman 上测试它们。我正在努力让它工作的 api 正在删除一篇文章。(注意:为了简洁起见,我只包含了有问题的代码,即app.delete(\'/articles/:id\' ....from app.js,以及它调用的静态方法model.js ,以及它从-deleteOneArticleFromDB(articleID)
app.js:
const express = require(\'express\');\nconst bodyParser = require(\'body-parser\');\nconst model = require(\'./model\');\n\nconst app = express();\n\napp.use(bodyParser.urlencoded({ extended: true }));\n\napp.delete(\'/articles/:id\', async (req, res) => {\n const articleID = req.params.id;\n console.log(`req.params.id: ${req.params.id}`);\n try {\n const response = await model.DBUtility.deleteOneArticleFromDB(articleID);\n res.status(200).json({message: response, app: \'wiki-api\'});\n } catch (err) {\n res.json({message: err, app: \'wiki-api\'});\n }\n});\n\nconst port = 3000;\napp.listen(port, () => {\n console.log(`Server started on port ${port}`);\n});\nRun Code Online (Sandbox Code Playgroud)\n\nmodel.js:
const mongoose = require(\'mongoose\');\n\nmongoose.connect(\'mongodb://localhost:27017/wikiDB\', {useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false });\n\nconst articleSchema = new mongoose.Schema({\n title: String,\n content: String\n});\n\nconst Article = mongoose.model(\'Article\', articleSchema);\n\nclass DBUtility {\n\n static deleteOneArticleFromDB(articleID) {\n return new Promise((resolve, reject) => {\n Article.findByIdAndDelete(articleID, (err) => {\n if (err) {\n reject(err);\n } else {\n resolve(`Deleted article ${articleID} successfully`);\n }\n });\n });\n }\n}\n\nexports.DBUtility = DBUtility;\nRun Code Online (Sandbox Code Playgroud)\n\n我的数据库中有 5 篇文章(5 个文档):
\n\n{\n "_id" : "5c139771d79ac8eac11e754a",\n "title" : "API",\n "content" : "API stands for Application Programming Interface. It is a set of subroutine definitions, communication protocols, and tools for building software. In general terms, it is a set of clearly defined methods of communication among various components. A good API makes it easier to develop a computer program by providing all the building blocks, which are then put together by the programmer."\n}\n\n/* 2 */\n{\n "_id" : "5c1398aad79ac8eac11e7561",\n "title" : "Bootstrap",\n "content" : "This is a framework developed by Twitter that contains pre-made front-end templates for web design"\n}\n\n/* 3 */\n{\n "_id" : "5c1398ecd79ac8eac11e7567",\n "title" : "DOM",\n "content" : "The Document Object Model is like an API for interacting with our HTML"\n}\n\n/* 4 */\n{\n "_id" : "5ea2c188fa57aa1b6453eda5",\n "title" : "Node JS",\n "content" : "Node.js is an open-source, cross-platform, JavaScript runtime environment that executes JavaScript code outside of a web browser. Node.js lets developers use JavaScript to write command line tools and for server-side scripting\xe2\x80\x94running scripts server-side to produce dynamic web page content before the page is sent to the user\'s web browser. Consequently, Node.js represents a \\"JavaScript everywhere\\" paradigm,[6] unifying web-application development around a single programming language, rather than different languages for server- and client-side scripts.",\n "__v" : 0\n}\n\n/* 5 */\n{\n "_id" : "5ea2d5304e19b11e0013a86a",\n "title" : "EJS",\n "content" : "EJS is a simple templating language that lets you generate HTML markup with plain JavaScript. No religiousness about how to organize things. No reinvention of iteration and control-flow. It\'s just plain JavaScript",\n "__v" : 0\n}\nRun Code Online (Sandbox Code Playgroud)\n\n我正在尝试删除最后一篇标题为 的文章(文档)EJS。所以在 Postman 中我运行 http 请求如下:
如您所见,我得到了成功的响应。但是,当我检查数据库时,该文档仍然存在(我已多次单击刷新,并使用 GET 请求测试它以返回所有文章,这表明该文章仍然存在):\n
这是终端输出:
\n\n[nodemon] starting `node app.js`\nServer started on port 3000\nreq.params.id: 5ea2d5304e19b11e0013a86a\nRun Code Online (Sandbox Code Playgroud)\n\n我已经研究这个问题两天了。我已经检查了之前所有与我的标题相似的 SO 帖子,但我找不到适用于我的问题的帖子。我不明白我哪里错了!!任何帮助将非常感激。
\n\n更新
\n\n根据 Mohammed Yousry 下面的解决方案,我意识到我_id使用字符串手动添加了该字段,因为我正在遵循教程。因此不允许 MongoDB 创建该_id字段,作为ObjectId. 因此,我的_id字段是 String 类型而不是 ObjectId 类型。因此,为了解决这个问题,我从数据库中删除了所有文档并重新添加它们,使用 POSTMAN 和我创建的 POST 方法 - 用于创建/添加新的文章文档到数据库,仅提供请求正文中的title和字段。因此,允许 MongoDB为每个文章文档content创建字段。_id现在在数据库中该_id字段的类型为ObjectId。这仍然没有完全解决我的问题,但又向前迈进了一步。仍在努力达成解决方案。请参阅下面解决方案部分的讨论。
1-可能是你的mongoose版本不支持findByIdAndDelete
尝试findByIdAndRemove代替
2-您可以将 id 作为字符串或 objectId 传递给该方法
确保您传递的 ID 正确且不带任何空格
const articleID = req.params.id.toString().trim(); // trim will remove any spaces before or after the id
Run Code Online (Sandbox Code Playgroud)
根据这张图片
看来您已手动插入数据,并且这些数据包含作为_id字符串,因为_id这里的类型是字符串,正如您在此图中看到的那样
我建议你让自己MongoDB设置_id
如果您可以将_id类型更改为ObjectId
或者如果您无法更改 的类型_id,您可以备份您的文章,然后手动删除所有这些文章并在没有 _id 的情况下再次添加它们,让 mongoDB 设置该 _id,然后再次尝试您的代码
希望这可以解决问题
检查了 github 中的代码后,我知道你出现这种奇怪行为的原因
app.route('/articles/:articleTitle')1-您在路线之前定义了路线app.delete('/articles/:id'
因此,当您尝试通过传递 id 来删除某些文章时,nodeJS Express 会将其传递给第一个匹配的路由,因为它不知道您发送的内容,它正在搜索中的params基础,因此它处理第一个路由与:匹配,将其作为文章标题urlrouteurl'/articles/something'
然后调用该deleteOneArticleByTitleFromDB方法
然后,MongoDB 正在搜索一些标题为您传递的 id 的文章,它什么也没找到,然后,它不会删除任何文章
2-我建议你不要定义一些具有相同基本url的路由
所以你可以通过 Id 路由定义删除,如下所示
app.delete('/arti/cles/:id', async (req, res) => // note the slash inside articles word
Run Code Online (Sandbox Code Playgroud)
或除当前的之外的任何您想要的内容
这样你就可以避免路线之间的这种矛盾
| 归档时间: |
|
| 查看次数: |
10840 次 |
| 最近记录: |