Pass variables to mongodb query in nodejs - node.js

Can I pass a variable to a query so:
db.collection('coll').find(query).toArray(function(err, docs) {
if(err) throw err;
docs.forEach(function(doc) {
var Id = parseInt(doc._id); // a returnd _id from previous query
Id--;
query = {_id : parseInt(doc._id) }; // returns null
// OR query = {_id : Id }; // error
db.collection('coll').find(query).toArray(function(err, beforeDocs) {
//if (err) throw err;
console.dir(beforeDocs);
});
});
In fact what I am trying to do is query by id to get the record that comes before the results given in the first query
Any ideas??
Is it at all possible to query mongodb with variables??
var query = { _id : var i, name : var name , etc...}

There is no way to search for the document that shows up before a match in a mongodb query.
I believe your best bet is something like this:
var prevDoc = null; // to store the previous document
var cursor = db.collection('collection').find({}); // get all docs
cursor.sort('_id', 1); // it only makes sense to grab previous if they're sorted
cursor.each(function(err, doc) {
if(err) throw err;
if(doc == null) { // if we reached the end of our cursor...
db.close(); // close the db connection
} else {
if( doc.foo === "bar" ) { // here you put your match criteria
console.dir(prevDoc); // here you print your previous document
}
}
prevDoc = doc; // store current doc so that it's available for next iteration
});
To answer your direct question ("Is it at all possible to query mongodb with variables?"), it is possible to query mongodb with a query which contains variables that already have values at the time the query is created. It is not possible, however, to pass new uninstantiated variables along for mongodb to manipulate somehow.

Related

Unable to find document with specified parameters in MongoDb using NodeJs

I am trying to find document match with specified ObjectId and post but in result it is alway returning available even if document is not present there.
This is my code below:
router.post('/check',(req,res) => {
MongoClient.connect(dburl,{useNewUrlParser:true},(err,client) => {
var ObjectId = require('mongodb').ObjectID;
var uId = { _id:new ObjectId(req.body.uId)};
var pId = req.body.pId;
if(err){
console.log("Error" +err);
}else{
var collect = client.db('Example').collection('Wishlist');
collect.find({_id:uId,postId:pId},(err,doc) => {
if(err){
console.log("Error" +err);
}if(doc){
res.send("Available");
}else{
res.send("Not available");
client.close();
}
});
}
});
});
Someone please let me know what I am doing wrong any help would be appreciated.
THANKS
Assuming you don't have middleware that transforms req.body.pId to an integer and that it's not a string value in your database, then your query will fail to find anything. 123 !== "123", after all. The query {_id:uId,postId:pId} is currently searching for for an ObjectId and a string.
Cast the value from the user's input to an integer:
var pId = parseInt(req.body.pId, 10);
Now the query {_id:uId,postId:pId} will search for an ObjectId and an integer.
Another thing that looks odd is that you have your _id value in an object. While that is possible in MongoDb, should it not be the following?
var uId = new ObjectId(req.body.uId);

find multiple items from mongoDB in nodejs

I want to find multiple things like item's ID and item's Item's Status.
but every time i get false.
Node.js code:
app.post('/product', function (req, res) {
var collection = req.db.get('itemslist');
var id = req.body.id;
var status = req.body.status;
collection.findOne({id: id, status: status}, function(e, doc){
console.log(id, status);
if (doc == true){
res.send('true');
}
else {
res.send('false');
}
});
});
where i am going wrong?
doc is a document and not a boolean. try if (!doc){ res.send('false'); } else { res.send('true');}
When you use collection.findone() it returns: "one document that satisfies the criteria specified as the first argument to this method."
i.e. the first document from your collection, a document is an object which contains all the data.
You can find more info here

Unable to delete a document with passed "email" and "_id" anyhow

I wanted to delete a document with concerned _id and email when I click on "Remove task" in the HTML file.
Following is the code which removes that task:
I've passed value of email and _id(only hexadcemial string value) to the code:
collection.findOneAndDelete({email:email,_id:taskid},function (err, result) {
if (err) {
console.log(err);
} else {
console.log("Removed!");
console.log(result);
callback(result);
}
db.close();
});
But, the function is not recognizing _id that I've passed. The value of "taskid" variable is 566836bd8db43d3d56e23a4a i.e. only strings value from _id:
ObjectId("566836bd8db43d3d56e23a4a")
var taskid=566836bd8db43d3d56e23a4a;
I've tried every possible declaration of taskid to convert it so that the function could recognize the value of _id and match it:
var taskid= "ObjectId("+'"'+req.param('taskid')+'"'+")";
But till now, I am not able to match the _id with the taskid. Any fix?
if you are going to compare with ObjectId then
var ObjectId = require('mongoose').Types.ObjectId
collection.findOneAndDelete({email:email,_id:new ObjectId(taskid)},function (err, result) {
if (err) {
console.log(err);
} else {
console.log("Removed!");
console.log(result);
callback(result);
}
db.close();
});
Should work for you.
If you feel the job too hard for each and every query then you can create an new method.
String.prototype.toObjectId = function() {
var ObjectId = (require('mongoose').Types.ObjectId);
return new ObjectId(this.toString());
};
// Every String can be casted in ObjectId now
console.log('545f489dea12346454ae793b'.toObjectId());

Object #<Promise> has no method 'limit'

when I run code
var collection = db.get('categories');
console.log(collection.find().limit(1).sort( { _id : -1 } ));
on nodejs using mongodb I am getting error Object # has no method 'limit' . I am a beginner to node and really stuck on this section of node
here is full code for geting last insert document.
router.post('/addcategory', function(req, res) {
// Set our internal DB variable
var db = req.db;
// Get our form values. These rely on the "name" attributes
var name = req.body.name;
var description = req.body.description;
// Set our collection
var collection = db.get('categories');
// Submit to the DB
collection.insert({
"name" : name,
"description" : description,
}, function (err, doc) {
if (err) {
// If it failed, return error
res.send("There was a problem adding the information to the database.");
}
else {
// And forward to success page
/******************/
console.log(collection.find().limit(1).sort( { _id : -1 } ));
/*************/
}
});
});
The key piece of missing information here was that you are using Monk, not the native MongoDB Node.JS driver. The command you have for find() is how you would use the native driver (with the changes suggested by #BlakesSeven above for asynchronity), but Monk works a little bit differently.
Try this instead:
collection.find({}, { limit : 1, sort : { _id : -1 } }, function (err,res) {
console.log(res);
});
The method is still asynchronous so you still need to invoke itm either as a promise with .then() or a callback. No methods are sychronous and return results in-line.
Also the result returned from the driver is s "Cursor" and not the object(s) you expect. You either iterate the returned cursor or just use .toArray() or similar to convert:
collection.find().limit(1).sort({ "_id": -1 }).toArray().then(function(docs) {
console.log(docs[0]);
});
Or:
collection.find().limit(1).sort({ "_id": -1 }).toArray(function(err,docs) {
console.log(docs[0]);
});
But really the whole premise is not correct. You seem to basically want to return what you just inserted. Event with the correction in your code, the returned document is not necessarily the one you just inserted, but rather the last one inserted into the collection, which could have occurred from another operation or call to this route from another source.
If you want what you inserted back then rather call the .insertOne() method and inspect the result:
collection.insertOne({ "name": name, "description": description },function(err,result) {
if (err) {
res.send("There was an error");
} else {
console.log(result.ops)
}
});
The .insert() method is considered deprecated, but basically returns the same thing. The consideration is that they return a insertWriteOpResult object where the ops property contains the document(s) inserted and their _id value(s),

Inserting multiple document into MongoDB with Mongoskin

I'm trying to insert several documents trough a loop, but I get a problem with the uniqueness of the ObjecId's.
I have this function:
// Fetch all client documents.
db.collection('clients').find({}, {cost: 1}).toArray(function(err, dbDocs) {
if (err) throw err;
// Set up a general doc.
var currentTime = new Date();
var doc = {
year: currentTime.getFullYear(),
quarter: Math.floor(currentTime.getMonth() / 3) + 1,
paid: false
};
// For each client document, insert a document to invoices collection.
for (var i = 0, j = dbDocs.length; i < j; i += 1) {
doc.quarterCost = (dbDocs[i].cost.monthly * 3);
doc.client_id = dbDocs[i]._id;
db.collection('invoices').insert(doc, function(err, result) {
if (err) throw err;
if (result) console.log('Invoice created');
});
}
});
I get a "mongoError: E110000 Duplicate key error index: ... " after the first document is created and inserted.
Question: Why are this loop trying to insert every document with the same ObjectID, and therefore generation an error? How do i rewrite this to make sure the ObjectId is random every time?
On the first insert, doc is modified to have the new _id field. Which means that you need to reset it at the start of your for loop as drivers don't add a new _id value to a document if there is already one.

Resources