I have careted an application that interacts with MongoDb using NodeJS (Express JS). I am trying to remove a document using the "_id" (the one generated by MongoDB). The following piece of code just logs "Deleted Successfully", but does not actuall remove the record:
app.post('/TaskDone', function (req, res) {
var mongo = require('mongodb'),
Server = mongo.Server,
Db = mongo.Db;
var server = new Server('localhost', 27017, { auto_reconnect: true });
var database = new Db('pending-list-2', server);
database.open(function (err, db) {
if (!err) {
console.log("Connected for Deletion");
db.collection('tasks', function (err, coll) {
var str = "{_id :"+"ObjectId(" + "\"" + req.body + "\"" + ")" + "}";
console.log(str);
coll.remove(str, function (err) {
if (err) console.log(err);
else console.log("Deleted successfully");
}
);
});
}
});
});
If I use the MongoDB client and just run db.tasks.remove({_id:ObjectID("idhere")}) , it works. Is there something wrong with the express js code that I have written. I have tried a lot of things but nothing seems to work.
You must create an ObjectID from the mongodb library:
Also this is expected that you do not have any error. The remove() is executed, but the filter is probably invalid.
So you will have to write something like like:
var mongodb = require('mongodb');
...
...
collection.remove(
{_id: new mongodb.ObjectID( req.body) },
function (err, result){
//check result to see how many document are deleted
});
Try as below:
var id = {
_id: req.body.id
};
var collection = db.collection("tableName");
collection.remove(id, function(err, records){
if(err){
console.log("Error" + err);
}
else{
console.log("Omega Job Removed");
}
});
Related
I was recently using a function to upload files to a mongodb database successfully. However after moving those functions into a file (to clean up) and exporting that file then requiring it in my route, the database now creates documents with only null values like so:
_id:ObjectId("xxxxxxxxxxxxxxx")
name:null,
value:null,
image:null,
desc:null
I don't know what might be causing this, I am logging the argument object that i'm trying to insert from inside the function 'insertProducts' and the item.name is not null. Sorry I'm new to mongodb :/
maybe someone can point me in the right direction?
CRUD.js
const mongodb = require('mongodb');
const MongoClient = mongodb.MongoClient;
const removeProducts = function(req,res){
MongoClient.connect('mongodb://localhost', (err, client) => {
if (err) {
throw err;
}
let db = client.db('account-app');
let products = db.collection('products');
let users = db.collection('users');
try{
products.remove({ _id: req.body.id }, function(err) {
if (!err) {
console.log('removed item')
}
});
}
catch(err){
console.log('Error while inserting', err)
}
client.close()
res.redirect('/addItems')
})
}
const insertProducts = function(item,res){
console.log("item name",item.name)
MongoClient.connect('mongodb://localhost', (err, client) => {
if (err) {
throw err;
}
let db = client.db('account-app');
let products = db.collection('products');
try{
products.insertOne(item)
console.log('item inserted')
}
catch(err){
console.log('Error while inserting', err)
}
client.close()
res.redirect('/admin/addItems')
})
}
module.exports={removeProducts: removeProducts, insertProducts: insertProducts}
my admin route that requires the crud functions
const crudOps = require('../utils/admin/CRUD') //require CRUD functions
// Adding new items
// --------------------------------------------------
router.post('/addNewItems', (req, res, next) => {
console.log(req.body.name)
let item = {
name:req.body.name,
file: binary(req.files.image.data),
value: req.body.value,
desc: req.body.desc
}
crudOps.insertProducts(item, res)
});
That connection URL looks wrong. Generally, it has the format:
mongodb://localhost:27017/mydatabase
Try replacing the connection string with the appropriate one for your database and see if that works. Also, the docs normally have insertOne statements like this so maybe that is the issue?
products.insertOne(item, function(err, r) {
console.log('item inserted')
res.redirect('/admin/addItems')
db.close();
});
db.js
var mongodb = require('mongodb').MongoClient;
var settings = require("./settings.js");
var ObjectId = require('mongodb').ObjectID;
var db = {
selectData: function(collection, query, callback, project = false) {
mongodb.connect(settings.db_url, function(err, client) {
var database = client.db(settings.db_name);
if (err) throw err;
if (project !== false) {
console.log("Project is not false");
console.log( project);
database.collection(collection).find(query, project).toArray(function(err, result) {
client.close();
if (err) throw err;
callback(result);
});
} else {
database.collection(collection).find(query).toArray(function(err, result) {
client.close();
if (err) throw err;
callback(result);
});
}
});
}
}
module.exports = db;
server.js
here is a simple query with single database call takes few seconds not a big deal but still not good method as per experts.
var db = require("db.js");
db.selectData("testCollection",{},function(data){
console.log(data);
});
Now here is a multi query nested database calls which takes more time and really bad for performance and speed
var db = require("db.js");
db.selectData("testCollection", {}, function(data) {
db.selectData("testCollection", {}, function(data) {
db.selectData("testCollection", {}, function(data) {
db.selectData("testCollection", {}, function(data) {
db.selectData("testCollection", {}, function(data) {
console.log(data);
});
});
});
});
});
What i want is open connection once and use db object outside without connecting again and again for each request or nested querys for fast response
i also know that with mongodb nodejs 2.3 drivers its possible and i have tested it perfectly working but i am looking for solution how to do same with mongodb nodejs 3.0 drivers
in short i am looking for a method where i can connect once and execute querys faster for chat and real time applications and performance optimizations
thank you.
Here i found a great working code with nodejs 3.0 Mongodb drivers
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
var express = require('express');
var app = express();
const url = 'mongodb://Your connection string';
const dbName = 'your database name';
MongoClient.connect(url, function(err, client) {
const db = client.db(dbName);
app.get("/", function(req, res) {
db.collection("somedata").find({}).toArray(function(err, result) {
if (err) throw err;
res.send(JSON.stringify(result));
});
});
app.listen(3000);
});
Instead of connecting again and again for each request connect at once and use it for best way if database connection is lost you can connect again but here you have to use some logic to make live that connection again and app routes too
this works for me i hope it will work for developers looking for answers of this question
Here are the codes
var mongo = require('mongodb');
var databaseName = 'Starter',
collectionName = 'wines';
var Server = mongo.Server,
Db = mongo.Db,
BSON = mongo.BSONPure;
db = new Db(databaseName, server);
db.open(function(err, db) {
if(!err) {
console.log("Connected to 'winedb' database");
db.collection(collectionName, {strict:true}, function(err, collection) {
if (err) {
console.log("The 'wines' collection doesn't exist. Creating it with sample data...");
populateDB();
}
});
}
});
exports.findById = function(req, res) {
var id = req.params.id;
console.log('Retrieving wine: ' + id);
db.collection(collectionName, function(err, collection) {
collection.findOne({'_id':new BSON.ObjectID(id)}, function(err, item) {
res.send(item);
});
});
};
These codes are based on a sample of restful api for nodejs with mongoDB.
However, it seems that it cannot recognise the function findOne. Can someone point out the problem?
Error message:
TypeError: Cannot read property 'findOne' of undefined
findOne is deprecated in the latest version of mongodb#2.x
https://github.com/mongodb/node-mongodb-native/blob/2.0/lib/collection.js
You can use this query instead
find(query).limit(1).next(function(err, doc){
// handle data
})
In the first db.collection you send 3 arguments like:
db.collection(collectionName, {strict:true}, function(err, collection)
After you only send 2:
db.collection(collectionName, function(err, collection)
This should be your issue.
change the start of your code to
var mongo = require('mongodb');
mongo.BSONPure = require('bson').BSONPure;
var databaseName = 'Starter',
collectionName = 'wines';
var Server = mongo.Server,
Db = mongo.Db,
BSON = mongo.BSONPure;
use this
collection.findOne({'_id':new mongo.ObjectID(id)}, function(err, item) {
instead of
collection.findOne({'_id':new BSON.ObjectID(id)}, function(err, item) {
in your wine.js file
try to log collection to the console before using findOne or wrapping the whole thing in an:
if(err){log}
else{findone}
if(err){
console.log(err)
}
else{
collection.findOne({'_id':new BSON.ObjectID(id)}, function(err, item){
res.send(item);
}}
the reason it is not working is because collection in your error-first callback function is the parameter that gets assigned if the operation is successful ...
Useful link about the topic ....
You represent your collection in a variable called collectionName and you are trying to invoke findOne() on something called collection which wont work.
instead of :
collection.findOne({'_id':new BSON.ObjectID(id)}, function(err, item)
use:
collectionName.findOne({'_id':new BSON.ObjectID(id)}, function(err, item)
here is my model code to insert some records. On my work pc it works perfectly, but when I'm running it on my home pc with the same OS, collection.insert doesn't running its callback, so I get just long request which ends with time out. There are no errors, mongo db logs say "Connection accepted" 5 times, and after that there are no messages. The same happens when I try to fetch objects from database using find(). Inserting records with mongo shell works great, but with node.js I couldn't accomplish that.
/*
* POST populate locations.
*/
var MongoClient = require('mongodb').MongoClient,
_ = require('underscore'),
env = process.env.NODE_ENV || 'development',
config = require('../config/config')[env]
exports.connect = function(cb) {
MongoClient.connect(config.db, function(err, db) {
if (err) throw err;
cb(db)
});
}
exports.populate = function(data, cb) {
var self = this;
self.connect(function(db) {
var collection = db.collection('locations');
collection.insert(data, function(err, docs) {
collection.ensureIndex({
"loc": "2dsphere"
}, function() {
db.close();
cb();
});
});
});
}
Use
exports.populate = function(data, cb) {
MongoClient.connect(config.db, function(db) {
var collection = db.collection('locations');
collection.insert(data, function(err, docs) {
collection.ensureIndex({
"loc": "2dsphere"
}, function() {
db.close();
cb();
});
});
});
}
I'm trying to return the JSON data in a mongoose document, and then display it using Angular. There's no errors on the page when using this code. The $http.get method in the Angular IndexCtrl never makes it to success, which leads me to believe the problem is how I'm implementing the API get method. Any help rewriting that method to return properly greatly appreciated!
To clarify: what I want is to be able to access the document like a JSON Object so I can display the data to the client.
update: it does produce the error:
GET http://localhost:3000/api/tracks
It takes a while for that error to show in the console
the api method
app.get("/api/tracks", function(req, res) {
return Track.find({}, function (err, tracks) {
if (err) {
res.send(500);
return;
}
return res.json({
tracks: tracks
});
});
});
the mongoose database
var mongoose = require('mongoose');
var uristring =
process.env.MONGOLAB_URI ||
'mongodb://localhost/HelloMongoose';
var mongoOptions = { db: { safe: true }};
var db = mongoose.createConnection(uristring, mongoOptions, function (err, res) {
if (err) {
console.log ('ERROR connecting to: ' + uristring + '. ' + err);
} else {
console.log ('Succeeded connected to: ' + uristring);
}
});
//a Schema for a track
var Schema = new mongoose.Schema({
name: String,
location: String,
description: String
});
var Track = mongoose.model('Track', Schema);
var spot = new Track({name: 'zildjian'});
spot.save(function (err) {
console.log('saved');
if (err) // ...
console.log('meow');
});
The Angular controller
function IndexCtrl($scope, $http) {
$http.get('/api/tracks').
success(function(data, status, headers, config) {
$scope.tracks = data.tracks;
console.log($scope.tracks + "scope tracks data"); //This does not log! it never makes it this far
});
}
The Jade template that displays $scope.tracks
p There are {{tracks.length}} posts
div(ng-repeat='track in tracks')
h3 {{track.name}}
div {{track.description}}
I was not pulling the entries from the model correctly. Here is how I fixed it:
app.get("/api/tracks", function (req, res) {
var track = [];
var Track = mongoose.model('Track', trackSchema);
Track.find({}, function (err, records) {
records.forEach(function (post, i) {
track.push({
id: i,
title: post.title,
text: post.text.substr(0, 50) + '...'
});
});
res.json({
track: track
});
});
};
}