Reputation: 4855
I am trying to build a simple web service in NodeJS/Express using the MongoDB 2.0.0 driver.
UPDATE: Based on prior feedback I removed the db.close() I had and rearranged my code
When I execute my GET all (no filter) method or my POST or PUT methods everything works as expected.
However, if I execute the GET (specific) method, I receive an error like the following:
---------------------------------------------------------------
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)
Below is my index.js file:
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;
}
}
Below is my sample data returned by the GET all (no filter method):
[{"_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":"[email protected]","phone":"","isActive":"true","dateCreated":"2015-03-14T04:39:45.711Z","dateModified":"2015-03-14T04:39:45.711Z"}]
Upvotes: 0
Views: 145
Reputation: 151122
The "main" problem here after all the other problems you had is that filter
here is a "string" and not a query "object". You should rather construct it like this:
var filter = {};
filter[request.params.identifier] = request.params.value;
That said, the title of your question seems to be about using an ObjectId
in the query, so as commented earlier, you need to "cast" that first since the "string" in the request will not otherwise match:
var ObjectID = require('mongodb').ObjectID;
var filter = {};
filter[request.params.identifier] =
( request.params.identifier == "_id" ) ?
new ObjectID(request.params.value) :
request.params.value;
Or some logic like that considering the "mapping" of your fields to the "type" they actually have in storage. But is is also worth noting that your actual data does not appear to have an actual ObjectId() type or any other specific type. But you need to do such a thing where it does.
There are other things in your code that you really should not do such as :
db.collection(mongoCollection).findOneAndUpdate( // bad!
It's not safe since there is no real guarantee that the collection actually existed. You also would be better off writing like this:
db.collection(mongoCollection,function(err,collection) {
collection.findOneAndUpdate(filter,{ "$set": requestBody },function(err,doc) {
And noting that the "options" as you specified them are the default values anyway.
That should get you going, but if you run into more problems then you really need to ask another question rather than keep adding to an existing question where the problems were pointed out or answers given relating to the actual question you were asking at the time.
Also note that you are referencing the syntax from the Node driver 2.0.x series, so make sure you have that version installed or otherwise use the methods as described in the 1.4.x series documentation.
It's not good behavior here to ask, "I have this problem, thanks", then "Oh but now I got this other error when I changed it." as you have essentially done here.
Also break your questions into small parts and focus on the specific problem. Throwing out your entire listing is bound to have multiple issues everywhere and is generally too broad for people to answer.
Upvotes: 1