Reputation: 1286
Been messing around with the NodeJS + MongoDB + Express stack, and came across an issue with performing queries. I have some helper methods in my index.js file:
var mongoClient = new MongoClient(new Server(mongoHost, mongoPort)); //B
mongoClient.open(function(err, mongoClient) { //C
if (!mongoClient) {
console.error("Error! Exiting... Must start MongoDB first");
process.exit(1); //D
}
var db = mongoClient.db("trackr"); //E
collectionDriver = new CollectionDriver(db); //F
});
app.use(express.static(path.join(__dirname, 'public')));
app.get('/:collection', function(req, res) { //A
var params = req.params; //B
collectionDriver.findAll(req.params.collection, function(error, objs) { //C
if (error) { res.send(400, error); } //D
else {
if (req.accepts('html')) { //E
res.render('data',{objects: objs, collection: req.params.collection}); //F
} else {
res.set('Content-Type','application/json'); //G
res.send(200, objs); //H
}
}
});
});
app.get('/:collection/:entity', function(req, res) { //I
var params = req.params;
var entity = params.entity;
var collection = params.collection;
if (entity) {
collectionDriver.get(collection, entity, function(error, objs) { //J
if (error) { res.send(400, error); }
else { res.send(200, objs); } //K
});
} else {
res.send(400, {error: 'bad url', url: req.url});
}
});
app.get('/:collection/iata/:value', function(req, res) { //I
console.log("entrou");
var params = req.params;
var value = params.value;
var collection = params.collection;
if (value) {
collectionDriver.getByIata(collection, value, function(error, objs) { //J
if (error) { res.send(400, error); }
else { res.send(200, objs); } //K
});
} else {
res.send(400, {error: 'bad url', url: req.url});
}
});
Problem here is - whenever I point to the "/collection/" route through a GET request, everything works fine - all the items from the collection are rendered. Also, if I point to the "/collection/entity" route, by providing an ObjectID, the particular item is also returned. And when I try a GET request for the /collection/iata/value, no objects are returned. However, when I perform the same query in the MongoDB prompt, the document is returned successfully.
Whole Collection Query
Query by ObjectID
Query by IATA Document Attribute
Query directly through MongoDB Prompt
In my index.js, I'm calling the functions from collectionDriver.js, code excerpt below:
CollectionDriver.prototype.findAll = function(collectionName, callback) {
this.getCollection(collectionName, function(error, the_collection) { //A
if( error ) callback(error);
else {
the_collection.find().toArray(function(error, results) { //B
if( error ) callback(error);
else callback(null, results);
});
}
});
};
CollectionDriver.prototype.get = function(collectionName, param, callback) { //A
console.log("Get by ObjectID");
this.getCollection(collectionName, function(error, the_collection) {
if (error) callback(error);
else {
var checkForHexRegExp = new RegExp("^[0-9a-fA-F]{24}$"); //B
if (!checkForHexRegExp.test(param)) callback({error: "invalid id"});
else the_collection.findOne({'_id':ObjectID(param)}, function(error,doc) { //C
if (error) callback(error);
else callback(null, doc);
});
}
});
};
CollectionDriver.prototype.getByIata = function(collectionName, attribute, callback) { //A
console.log('entrou no driver - encontrar por atributo - collectionName: ' + collectionName);
this.db.collection(collectionName, function(error, the_collection) {
if( error ) callback(error);
else the_collection.find({'iata': attribute}, function(error, collection) {
collection.count({}, function(error, numDocs){
console.log(numDocs);
});
});
});
};
I'm aware that ObjectID queries require conversion to BSON - am I missing some similar requirement when trying to query for a document's attribute?
Thanks in advance.
Upvotes: 3
Views: 581
Reputation: 12293
You are not returning anything from getByIata
prototype
CollectionDriver.prototype.getByIata = function(collectionName, attribute, callback) { //A
console.log('entrou no driver - encontrar por atributo - collectionName: ' + collectionName);
this.db.collection(collectionName, function(error, the_collection) {
if( error ) callback(error);
else the_collection.find({'iata': attribute}, function(error, doc) {
if (error) callback(error);
else callback(null, doc);
});
});
};
Upvotes: 4