我正在尝试使用MongoDB 2.0.0驱动程序在NodeJS / Express中构建一个简单的Web服务。
更新:根据先前的反馈,我删除了我的db.close()并重新安排了我的代码
当我执行我的GET all(无过滤器)方法或我的POST或PUT方法时,一切都按预期工作。
但是,如果我执行GET(特定)方法,我会收到如下错误:
---------------------------------------------------------------
Connected to MongoDB: mongodb://localhost:27017/example
Request URL: /jobs/profileID/1QtG8i88Sq
Method: GET [Retrieve Specific]
Collection: jobs
Filter: {"profileID":"1QtG8i88Sq"}
Error
at Error.MongoError (/apps/services.example.org/node_modules/mongodb/node_modules/mongodb-core/lib/error.js:13:17)
at Collection.find (/apps/services.example.org/node_modules/mongodb/lib/collection.js:269:11)
at /apps/services.example.org/index.js:80:35
at Layer.handle [as handle_request] (/apps/services.example.org/node_modules/express/lib/router/layer.js:82:5)
at next (/apps/services.example.org/node_modules/express/lib/router/route.js:110:13)
at jsonParser (/apps/services.example.org/node_modules/body-parser/lib/types/json.js:96:40)
at Layer.handle [as handle_request] (/apps/services.example.org/node_modules/express/lib/router/layer.js:82:5)
at next (/apps/services.example.org/node_modules/express/lib/router/route.js:110:13)
at Route.dispatch (/apps/services.example.org/node_modules/express/lib/router/route.js:91:3)
at Layer.handle [as handle_request] (/apps/services.example.org/node_modules/express/lib/router/layer.js:82:5)
以下是我的 index.js 文件:
var error404 = 'http://example.org/404';
var expressPort = 8080;
var mongoConnectionString = 'mongodb://localhost:27017/example';
var mongoConnectedMessage = '\n---------------------------------------------------------------\n\nConnected to MongoDB: ' + mongoConnectionString;
/* ------------------------------------------------------------------------- */
var assert = require('assert');
var express = require('express');
var http = require('http');
var bodyParser = require('body-parser');
var jsonParser = bodyParser.json();
var urlencodedParser = bodyParser.urlencoded({ extended: false });
var MongoClient = require('mongodb').MongoClient;
// Configure Express
var app = express();
app.set('port', process.env.PORT || expressPort);
app.use(bodyParser.json());
// Configure CORS (Cross-Origin Resource Sharing) Headers
app.all('*', function(request, response, next) {
response.header("Access-Control-Allow-Origin", "*");
response.header("Access-Control-Allow-Headers", "X-Requested-With");
response.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});
/* ------------------------------------------------------------------------- */
MongoClient.connect(mongoConnectionString, function(error, db) {
assert.equal(null, error);
// Create
app.post('/:collection', urlencodedParser, function(request, response) {
if (IsValidRequest(request.url)) {
var requestBody = request.body;
var mongoCollection = request.params.collection;
console.log(mongoConnectedMessage + '\nRequest URL: ' + request.url + '\nMethod: POST [Create] \nCollection: ' + mongoCollection + '\n');
db.collection(mongoCollection).insertOne(requestBody, function(error, documents) {
if (error) {
console.log(error);
response.status(400).send(error);
}
else {
response.status(201).send(documents);
}
return;
});
}
});
// Retrieve (All)
app.get('/:collection', jsonParser, function(request, response) {
if (IsValidRequest(request.url)) {
var mongoCollection = request.params.collection;
console.log(mongoConnectedMessage + '\nRequest URL: ' + request.url + '\nMethod: GET [Retrieve All] \nCollection: ' + mongoCollection + '\n');
db.collection(mongoCollection).find({}).toArray(function(error, documents) {
if (error) {
console.log(error);
response.status(400).send(error);
}
else {
response.status(201).send(documents);
}
return;
});
}
});
// Retrieve (Specific)
app.get('/:collection/:identifier/:value', jsonParser, function(request, response) {
if (IsValidRequest(request.url)) {
var mongoCollection = request.params.collection;
var filter = '{"'+request.params.identifier+'":"'+request.params.value+'"}';
console.log(mongoConnectedMessage + '\nRequest URL: ' + request.url + '\nMethod: GET [Retrieve Specific] \nCollection: ' + mongoCollection + '\nFilter: ' + filter + '\n');
db.collection(mongoCollection).find(filter).toArray(function(error, documents) {
if (error) {
console.log(error);
response.status(400).send(error);
}
else {
response.status(201).send(documents);
}
return;
});
}
});
// Update
app.put('/:collection/:identifier/:value', urlencodedParser, function(request, response) {
if (IsValidRequest(request.url)) {
var requestBody = request.body;
var mongoCollection = request.params.collection;
var filter = '{"'+request.params.identifier+'":"'+request.params.value+'"}';
console.log(mongoConnectedMessage + '\nRequest URL: ' + request.url + '\nMethod: PUT [Update Specific] \nCollection: ' + mongoCollection + '\nFilter: ' + filter + '\n');
db.collection(mongoCollection).findOneAndUpdate(filter, {$set: requestBody}, {
returnOriginal: false,
upsert: false
}, function(error, documents) {
if (error) {
console.log(error);
response.status(400).send(error);
}
else {
response.status(201).send(documents);
}
return;
});
}
});
// If all else fails...
app.use(function (request, response) {
response.redirect(error404);
});
});
/* ------------------------------------------------------------------------- */
http.createServer(app).listen(app.get('port'), function(){
console.log('Express Server Port: ' + app.get('port'));
});
/* ------------------------------------------------------------------------- */
function IsValidRequest(url) {
//console.log('URL: ' + url);
if (url !== '/favicon.ico') {
return true;
}
else {
return false;
}
}
以下是GET all返回的示例数据(无过滤方式):
[{"_id":"5503bb957e4eacd821b5c046","profileID":"1QtG8i88Sq","organization":"Acme Corp","title":"Sample Job","description":"Pellentesque vel turpis quis urna venenatis malesuada eu sit amet mi. Vivamus sit amet enim vitae sem convallis egestas. Nunc ac dui ac est euismod finibus id ut nulla. Donec malesuada ex risus, quis tincidunt dui semper eget. Proin eleifend, lectus consectetur sodales maximus, urna est malesuada eros, a pharetra metus mauris vitae felis. Vestibulum sit amet nisi euismod, pellentesque nunc sit amet, commodo nibh. Sed dignissim nunc nec diam pretium placerat. Nulla pellentesque nulla et varius molestie. Donec pulvinar, libero non placerat scelerisque, urna metus tincidunt nibh, suscipit aliquam felis mi non tortor. Sed et urna dolor. Nunc posuere arcu id sapien egestas dapibus. Sed ac est quis nunc rutrum tristique euismod pellentesque nibh.\\n\\nPellentesque vitae tempor elit. Ut urna arcu, aliquet nec turpis commodo, posuere facilisis purus. Phasellus ac tempus lacus, vel hendrerit lacus. Morbi porta mollis commodo. Mauris pellentesque justo eu enim sagittis, sit amet varius eros dapibus. Cras congue porttitor facilisis. Nunc rutrum nibh arcu, non eleifend nibh consectetur ac. Ut orci leo, vehicula eget efficitur quis, lobortis ut dolor. Morbi eu justo tristique, lobortis arcu eget, consectetur quam. Sed eget elementum est.","hireType":"Permanent","telecommute":"No","travel":"Yes - Part Time","hourlyPayRangeLow":"50","hourlyPayRangeHigh":"75","city":"Phoenix","stateProvince":"AZ","linkedInUrl":"","url":"https://careers.acmecorp.com/sample-job","email":"careers@acmecorp.com","phone":"","isActive":"true","dateCreated":"2015-03-14T04:39:45.711Z","dateModified":"2015-03-14T04:39:45.711Z"}]
答案 0 :(得分:1)
" main"在你遇到的所有其他问题之后,这里的问题是filter
这里是"字符串"而不是查询"对象"。你应该像这样构建它:
var filter = {};
filter[request.params.identifier] = request.params.value;
那就是说,你的问题的标题似乎是在查询中使用ObjectId
,所以如前所述,你需要" cast"首先是"字符串"在请求中将不会匹配:
var ObjectID = require('mongodb').ObjectID;
var filter = {};
filter[request.params.identifier] =
( request.params.identifier == "_id" ) ?
new ObjectID(request.params.value) :
request.params.value;
或者考虑到"映射"您的字段到"类型"他们实际上有存储空间。但值得注意的是,您的实际数据似乎没有实际的ObjectId()类型或任何其他特定类型。但是你需要做它做的事情。
您的代码中还有其他一些您不应该执行的操作,例如:
db.collection(mongoCollection).findOneAndUpdate( // bad!
它不安全,因为没有真正保证收集实际存在。你最好这样写:
db.collection(mongoCollection,function(err,collection) {
collection.findOneAndUpdate(filter,{ "$set": requestBody },function(err,doc) {
并注意到"选项"如你所指定的那样,无论如何都是默认值。
这应该让你去,但如果你遇到更多的问题,那么你真的需要提出另一个问题,而不是继续添加一个现有的问题,指出问题或给出与你提出的实际问题相关的答案时间。
另请注意,您正在引用Node driver 2.0.x series中的语法,因此请确保已安装该版本或以其他方式使用in the 1.4.x series documentation所述的方法。
这里不好的行为要问,"我有这个问题,谢谢"然后"哦,但是现在当我改变它时我得到了另一个错误。&#34 ;你基本上已经在这里完成了。
同样将问题分成小部分,并专注于具体问题。抛弃整个列表必然会在各处出现多个问题,而且通常过于宽泛,人们无法回答。