find multiple items from mongoDB in nodejs - node.js

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

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);

Update Document including empty fields via Mongoose

I'm sending the following object for mongoose to update:
{
"name" : "John",
"fruit" : "5a3d678d9b1549979d81c6ba" // this is an objectID
}
and the method:
db_user.findByIdAndUpdate(req.params.id, req.body).then(function(user, err) {
res.send(user);
});
This works fine if I replace the fruit with another fruitID which is what I'm trying to update.
However, if I send an object with no fruit, it won't remove the fruit field from the user document. Such as:
{
"name" : "John"
}
It will update whatever name I pass, but it won't remove the fruit field. Why?
Also: I can't be checking for each field that I'm sending or not and do an $unset for each accordingly, because I'm sending a lot of fields. I just want Mongoose to override the old document with the new one.
I know this is a little complicated / ugly and I'm sure there is an easier way but this should work if you want to update on specific thing and not have it fill the other values in blank.
function updateItem(req, res) {
function GetObjectFromKeyValuePairs(pairs) {
var tmp = {};
for(var key in pairs)
if(key[0] !== "_")
if(pairs[key].length !== 0)
tmp[`${key}`] = `${pairs[key]}`;
return tmp;
}
let updateOnlyChangedVals = GetObjectFromKeyValuePairs(req.body);
DB.Item.update({_id: req.params.id}, {$set: updateOnlyChangedVals},{new:true}, (err, uItem) => {
if (err) { return console.log("index error: " + err); }
res.json(uItem);
});
}

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),

Pass variables to mongodb query in nodejs

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.

mongodb query with javascript, cursor methods

I am just creating a simple user login for using MongoDB, Backbone and Node with Express.
I am stuck on querying the database for the user credentials and reliably identifying whether they exist or not.
I'm trying two things here:
// When user posts to the url
app.post('/save/user', function (req, res) {
// create user object and store email from form
var user = {
email : req.body.email
};
// in my collection users
db.collection('users', function (err, collection) {
// create a variable existence with the value, in lamens terms 'yes it does' or 'no it doesnt'
var existence = findOne(collection, {
$query : {email : user.email}
});
});
};
// findOne function passing the collection and the query object
function findOne(coll, query) {
var cursor = coll.find(query).limit(1);
return cursor.hasNext() ? cursor.next() : null;
}
So this is the first way I've been trying. Thing is, I don't understand why the cursor doesn't have 'next(), hasNext(), findOne(), forEach()' and other methods for javascript environment but only for mongo shell.
My question is, how do I access these methods from in my Node.js app?
The second way I tried it :
// When user posts to the url
app.post('/save/user', function (req, res) {
// create user object and store email from form
var user = {
email : req.body.email
};
// in my collection users
db.collection('users', function (err, collection) {
// Have a look for the email entered
var query = collection.find({
$query : {email : user.email}
}).limit(1);
// If it's true, then send response
query.each( function (err, item) {
// If the item does exists, then send back message and don't insert. Otherwise, insert.
if(item !== null) {
console.log('Item does not equal null : ', item);
res.send('The email : ' + item.email + ' already exists');
} else {
console.log('Item does equal null : ', item);
collection.insert(user);
res.send('New user with email : ' + user.email + ' was saved');
}
});
});
};
The problem with this is, it's always going to return null at some point and so I am going to warn the user 'it already exists' and then the next time will be null so it's going to save the email.
I think i'm missing the point so a point in the right direction would be great.
Many thanks in advance!
Well i've looked into a solution but still must be missing the point.
I'm doing an insert, passing in my user object with safe : true but although multiple user objects can be entered, it's still only looking for identical ID;s. I've tried creating an id with new ObjectID() but I still don't understand if a user enters their email adress, thenattempts to create a new user with the same email, it would create a new id for that entry.
By doing the findOne, I can see if it exists easily, Idon't see how it can be done with insert.
app.post('/register/user', function (req, res) {
// Store user details in object
var user = {
username : req.body.user,
email : req.body.email,
password : req.body.password
};
db.collection('users', function (err, collection) {
collection.insert(user, {safe : true}, function (err, doc) {
console.log('what is doc : ', doc);
if(!err) {
res.writeHead(200, {
"Content-Type" : "text/plain",
"Message" : "New user added",
"Access-Control-Allow-Origin" : "*"
});
} else {
console.log('Error is : ', err);
res.writeHead(200, {
"Content-Type" : "text/plain",
"Message" : "User already exists",
"Access-Control-Allow-Origin" : "*"
});
}
res.end();
});
});
});
If you're using the Native Node.JS MongoDB driver, there is a collection.findOne() method and cursors do have nextObject() and each() methods equivalent to the shell methods hasNext() and forEach(). The implementation/naming of the mongo shell equivalents can vary slightly between drivers but you should be able to translate mongo shell examples into Node.JS.
As far as saving a new user goes .. instead of querying for the user before inserting, you would be better to add a unique index on the email field and insert into the collection with safe:true. You can then handle the err result if the insert fails due to a duplicate email. If you do a query before insert there is a potential race condition where the email might not exist when you check for it, but does exist by the time you do the insert.

Resources