如何使用ExpressJS和Mongoose的PUT方法更新MongoDB数据库



我目前正在本地运行MongoDB 3.2.3版本。当前节点服务器版本7.2.0。API是用Typescript编写的。

相关依赖项列表:

"dependencies": {
"@types/mongoose": "^4.7.3",
"@types/node": "^6.0.56",
"bcrypt-nodejs": "0.0.3",
"body-parser": "^1.15.2",
"compression": "^1.6.2",
"dotenv": "^4.0.0",
"ejs": "^2.5.5",
"express": "^4.14.0",
"mongodb": "^2.2.21",
"mongoose": "^4.7.6",
"path": "^0.12.7"
}

我的server.js文件相关语句:

// Modules extending node
import * as express from 'express';
import * as bodyParser from 'body-parser';
import * as http from 'http';
import * as path from 'path';
// Custom modules imported.  Some are routers behaving as miniapps routed to the main app.
import { digitalAssetRouter } from './api/digitalMedia/digitalmediaController';
/**
* Node Express Server Controller
*/
let app = express();
app.use((req, res, next)=>{
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3050');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views/'));
let server = http.createServer(app);
//Configure express
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use((err, req, res, next) =>
res.status(500).send(JSON.stringify({ err: 'Bad API Request!' }))
);
//Route
app.use('/', indexRouter);
//API Routes
// API Information
app.use('/api/v1', digitalAssetRouter);
// Digital Assets
//GET ALL AND POST CREATE ONE
app.use('/api/v1/digitalassets', digitalAssetRouter); 
//GET ONE BY ID, PUT ONE BY ID, DELETE ONE BY ID
app.use('/api/v1/digitalassets/:digitalassetsId', digitalAssetRouter);
//UPDATE BY ID I TRIED BOTH WAYS, ABOVE AND BELOW
app.use('/api/v1/digitalassets/update/:digitalassetsId',      digitalAssetRouter);
// catch 404 and forward to error handler
app.use((req, res, next) => {
let err = new Error('Not Found');
err.message = '404';
next(err);
});
// error handler
app.use((err, req, res, next) => {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});

//server start
server.listen(3000, () => {
console.log('LOCALHOST Running @ port 3000');
console.log(app.get('env'));
});
//Expose server module
export { app };

以下是我的控制器相关方法:

/**
* Digital Media Controller Module
*/
import * as express from 'express';
import { digitalAsset } from './digitalmediaModel';
//Creates a mini app that only handles routes for digital assets
let digitalAssetRouter = express.Router();
/**
* UPDATE ONE BY ID
* Patch attributes for a model instance and persist it into the data source.
*/
digitalAssetRouter.put('/digitalassets/:digitalassetsId', (req, res, next) => {
console.log(req.params);
console.log(req.body);
digitalAsset.findByIdAndUpdate(req.params.digitalassetsId, req.body)
.then(response => {
res.status(200).json({
comment: 'Patch attributes for a model instance and persist it into the data source.',
responseType: 'success'
});
})
.catch(err => {
// console.log(err);
res.status(400).json({
error: "Cannot find digital image with id: " + req.params.digitalassetsId,
errorMessage: err
});
});
});

我直接从猫鼬那里阅读了关于findByIdAndUpdate的文档。我已经多次尝试修改通过邮递员发送数据更新的方式。

Postman PUT方法到api端点以按id更新我还将Content-Type-is-application/json放在了标题中。发送的有效负载是JSON格式的原始数据,如下所示。这是console.log(req.body)中显示的内容:

{
"altText" : "Canon alt text"
}

以下是我的数字资产模型:

/**
* Digital Media Model
*/
import { mongooseDb } from '../../config/db';
mongooseDb.Promise = global.Promise;
let Schema = mongooseDb.Schema;
let TagsSchema = new Schema({
id: String,
name: String,
app_id: String,
value: Number
},
{ _id: false });
let ExifSchema = new Schema({
make: String,
model: String,
width: Number,
length: Number,
created: String,
fileSource: String,
exposureMode: String,
exposureTime: String,
aperture: Number,
iso: Number,
exposureBias: Number,
flash: String,
orientation: String
},
{ _id: false });
let DigitalAssetSchema = new Schema({
fileName: String,
title: String,
caption: String,
altText: String,
description: String,
fileType: String,
uploadedOn: {
type: Date,
default: Date.now,
},
uploadedBy: String,
fileSize: {
type: Number,
},
url: {
type: String
},
relativePath: String,
categories: [String],
tags: [TagsSchema],
exif: ExifSchema,
embedUrl: String,
shareUrl: String
});
let digitalAsset = mongooseDb.model('digitalAsset', DigitalAssetSchema);
export { digitalAsset };

我在数据库中创建文档并删除它们没有问题。当涉及到使用快速路由通过PUT方法更新它们时,该过程不起作用。我尝试了不同的变体,只是为了更改所选文档中的一个字段,但没有成功。我在Postman中提供了以下截图示例:

我在MongoDB中有一些记录需要更新,如下所示。

{
"_id" : "589739a960aa6d23823cafb9",
"altText" : "CHANGE",
"description" : "CHANGE",
"relativePath" : "assets/Pics/high resolution/purchasable pictures/various.corbis/Internet/42-17083495.jpg",
"fileName" : "/disk/assets/Pics/high resolution/purchasable pictures/various.corbis/Internet/42-17083495",
"fileSize" : 8220,
"title" : "CHANGE",
"fileType" : ".jpg",
"caption" : "CHANGE",
"uploadedBy" : "rmore071",
"__v" : 0,
"tags" : [ 
{
"name" : "people",
"value" : 0.98049
}, 
{
"name" : "outdoors",
"value" : 0.9785451
}, 
{
"name" : "architecture",
"value" : 0.95540833
}, 
{
"name" : "horizontal plane",
"value" : 0.955212
}, 
{
"name" : "travel",
"value" : 0.95194626
}, 
{
"name" : "industry",
"value" : 0.9321301
}, 
{
"name" : "flame",
"value" : 0.9265379
}, 
{
"name" : "man",
"value" : 0.9220996
}, 
{
"name" : "business",
"value" : 0.91815794
}, 
{
"name" : "heat",
"value" : 0.89368707
}, 
{
"name" : "no person",
"value" : 0.89319044
}, 
{
"name" : "panoramic",
"value" : 0.8734973
}, 
{
"name" : "illuminated",
"value" : 0.8665502
}, 
{
"name" : "adult",
"value" : 0.86405236
}, 
{
"name" : "fossil fuel",
"value" : 0.8607676
}, 
{
"name" : "transportation system",
"value" : 0.8506778
}, 
{
"name" : "competition",
"value" : 0.83268094
}, 
{
"name" : "building",
"value" : 0.8307033
}, 
{
"name" : "action",
"value" : 0.8292489
}, 
{
"name" : "horizontal",
"value" : 0.829162
}
],
"categories" : [],
"uploadedOn" : "2017-02-05T14:41:45.984Z"
}

当我点击发送邮差时,我得到:

{
"comment": "Patch attributes for a model instance and persist it into the data source.",
"responseType": "success"
}

这告诉我,自从id被接受以来,promise没有返回错误,并打印出了then()函数中的内容。

然而,通过使用RoboMongo快速查看数据库,我发现字段altText尚未更新。

我的问题正是标题,我如何用PUT方法更新?我做错了什么,真的很想用另一双眼睛看一眼,看看我做错了些什么。提前感谢您抽出时间。

事实证明,作为我的_id键的值,它是数据库中的一个字符串。当我打开mongoose调试时,我注意到mongoose正在发送:Mongoose: digitalassets.findOne({ _id: ObjectId("58969de160aa6d23823c9e69") }, { fields: undefined }),数据库中的值是字符串。因此,响应将为null,因为查询没有找到值ObjectId("58969de160aa6d23823c9e69")。我通过将_id键的值从字符串更新为对象(即ObjectId("58969de160aa6d23823c9e69"))来纠正这个问题。

我怀疑,当我创建一个本地开发数据库环境并将一个子集文档从我的实时数据库复制到开发数据库时,ObjectId值被更改为字符串,从而导致从Mongoose的方法findByIdAndUpdate()中获取null响应的问题,该方法以PUT express路由执行。

最新更新