Node batch script with Mongoose : connection closed by app - node.js

scratched my head a big part of the night on this piece of the code.
Actually I need to process users account' subdocuments in a batch style. For sake if brevity, I just put part of the batch that's supposed to work... but it's not.
err: { [MongoError: Connection Closed By Application] name: 'MongoError' }
var mongoose = require('mongoose');
var dbURI = 'mongodb://localhost/testdb';
mongoose.connect(dbURI);
var UserSchema = new mongoose.Schema({ email: String, name: String });
var User = mongoose.model('User', UserSchema, 'users');
mongoose.connection.once('open', function() {
console.log("Connection opened, starting batch process."); /// this gets printed to console
User.find({},{},function(e,d){ // error is here somewhere & yes I got plenty of users in collection :)
if(e)console.log("err:",e);
console.log("doc:",d);
});
});
mongoose.connection.close();
All suggestions are more than welcome!
Thanks

Related

Async.each not working with post to database [duplicate]

var mongo = require('mongoose');
var connection = mongo.createConnection('mongodb://127.0.0.1/test');
connection.on("error", function(errorObject){
console.log(errorObject);
console.log('ONERROR');
});
var Schema = mongo.Schema;
var BookSchema = new Schema({ title : {type : String, index : {unique : true}}});
var BookModel = mongo.model('abook', BookSchema);
var b = new BookModel({title : 'aaaaaa'});
b.save( function(e){
if(e){
console.log('error')
}else{
console.log('no error')
}});
Neither the 'error', or 'no error' are printed to the terminal. What's more the connection.on 'error' doesn't seem to fire either. I have confirmed that MongoDb is running.
this is a case where you are adding the model to the global mongoose object but opening a separate connection mongo.createConnection() that the models are not part of. Since the model has no connection it cannot save to the db.
this is solved either by connecting to mongo on the global mongoose connection:
var connection = mongo.createConnection('mongodb://127.0.0.1/test');
// becomes
var connection = mongo.connect('mongodb://127.0.0.1/test');
or by adding your models to your separate connection:
var BookModel = mongo.model('abook', BookSchema);
// becomes
var BookModel = connection.model('abook', BookSchema);
I really like Aaron's answer, and thanks to him I am now on my way to fixing the issue... although I'm not there yet! Here is my particular issue:
I want to have my schema and models defined in separate files, so I can reuse them from project to project. So as an example I have a file named W8DBItem.js as follows:
var mongoose = require('mongoose');
var itemSchema = new mongoose.Schema({ name: {type: String, required: true}});
module.exports = mongoose.model('W8DBItem', itemSchema);
In my program file I do this this:
var mongoose = require('mongoose');
var W8DBItem = require('../w8/W8DBItem.js');
var dbURL ='mongodb://localhost:27017/default';
var mongoOptions = { useNewUrlParser: true, bufferCommands: false }
mongoose.connect(dbURL, mongoOptions);
var db = mongoose.connection;
// DEAL WITH CONNECTION ERROR
db.on('error', console.error.bind(console, 'connection error:'));
// PREP DATA
var aWeight = { name: "My Test Name" };
var newWeightItem = W8DBItem(aWeight);
// CONNECTION ESTABLISHED
db.once('open', function() {
console.log("Here 1")
// TRY TO SAVE
newWeightItem.save(function (err, newWeightItem) {
if (err) {
console.log("Here 2");
console.log(err);
}
else {
console.log("Here 3");
console.log(newWeightItem);
}
});
});
When I run this program I get "Here 1" but never "Here 2" or "Here 3" in the console.
From Aaron's post I get that the W8DBItem object has no associated (and open) connections, but I am not sure how to go about fixing things. I could connect to the DB in the W8DBItem.js file, but I really don't like hard-coding the server info with the objects - I want these objects to be used in different files, and perhaps with different servers.
Ideas and suggestions are much appreciated!
[EDIT: SOLUTION FOUND!!!]
Instead of exporting my mongoose.model from my object file, I am only exporting the schema:
var mongoose = require('mongoose');
var itemSchema = new mongoose.Schema({name: {type: String, required: true}});
module.exports = itemSchema;
In my program files I then do this:
var itemSchema = require('../w8/W8DBItemSchema.js');
...
var W8DBItem = db.model('W8DBItem', itemSchema);
var newWeightItem = W8DBItem(aWeight);
...
Works like a charm. I hope this helps someone!
The posted answer does not solve the problem. Unfortunately, I cannot just upgrade my database, so that is not a solution either for me. But here I found a solution to this problem: https://github.com/Automattic/mongoose/issues/4064
Just use .$__save instead of .save as shown:
var b = new BookModel({title : 'aaaaaa'});
b.$__save({}, function(e){
if(e){
console.log('error')
// callback will show if e exists
}else{
console.log('no error')
// callback will show 'no error'
}});

mongodb + mongoose: query not entering .find function

I am getting start with mongodb and mongoose but am having problems querying a database. There are a number of tutorials online for what I am trying to do but it just doesn't seem to work for me. My problem is that the .find() function is not even being called and the collection is not being displayed. I have a collection called Subjects in which I know there are some values (I manually entered them in the mongodb command line). I only tried including pertinent code but let me know if anything else is needed. Thanks in advance.
app.js file
require('./models/model.js');
var conn = mongoose.createConnection('mongodb://localhost/test');
var Subject = mongoose.model('Subjects');
Subject.find( { }, function (err, subjects) {
if(err) console.log("Error"); // There is no "Error"
console.log("Made it"); // There is no "Made it"
console.log(subjects);
});
model.js file
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var SubjectsSchema = new Schema ({
subject: { type: String }
});
module.exports = mongoose.model('Subjects', SubjectsSchema);
Call mongoose.connect instead of mongoose.createConnnection to open the default connection pool that will be used by models created using mongoose.model:
mongoose.connect('mongodb://localhost/test');

mongoose unique: true not work [duplicate]

This question already has answers here:
Unique index in mongoose not working
(1 answer)
Mongoose Unique index not working!
(35 answers)
Closed 8 years ago.
why mongoose unique not work at all in this script
var child_process = require('child_process');
// Load required packages
child_process.exec("mongo test --eval 'db.users.drop();'", function(err){
var mongoose = require('mongoose');
console.log(mongoose.version);
mongoose.connect('mongodb://localhost:27017/test');
// Define our user schema
var json = {};
json.phone = { type: String, required: true, unique: true};
var UserSchema = new mongoose.Schema(json);
var Model = mongoose.model('user', UserSchema);
var jp = new Model({ phone: "123456"});
mongoose.connection.on('open', function(){
console.log(jp);
jp.save(function(err){
console.log(err);
var jp2 = new Model({ phone: "123456"});
console.log(jp2);
jp2.save(function(err){
console.log(err);
process.exit();
});
})
});
});
I'm quite confused, the result is like
3.8.20
{ phone: '123456', _id: 54856cceb5b40f7a88fcc2af }
null
{ phone: '123456', _id: 54856cceb5b40f7a88fcc2b0 }
null
Thank you for your help.
This happens because you're saving the duplicated document before mongoose has finished creating the index. Mongoose creates the indexes on the go, after your app has started.
So, to ensure that your document will be saved only after the indexes were created, you have to listen to the index event of your model. For example:
Model.on('index', function (error) {
console.log(jp);
jp.save(function(err){
console.log(err);
var jp2 = new Model({ phone: "123456"});
console.log(jp2);
jp2.save(function(err){
console.log(err);
process.exit();
});
})
});
Now, when you try to save the second document (the duplicated one), your MongoDB will raise an error, because your save calls will just run after the indexes were created.

Mongoose ODM use

I read an article in this link http://theholmesoffice.com/mongoose-and-node-js-tutorial/
here there is a code:
exports.teamlist = function(gname,callback){
db.once('open', function(){
var teamSchema = new mongoose.Schema({
country: String,
GroupName: String
});
var Team = db.model('Team', teamSchema);
Team.find({'GroupName':gname}, function (err, teams) {
if(err){
onErr(err,callback);
}else{
mongoose.connection.close();
console.log(teams);
callback("",teams);
}
})// end Team.find
});// end db.once open
};
Here it calls db.once method whereas in other places its used like this
var mongoose = require('mongoose')
,Schema = mongoose.Schema
,ObjectId = Schema.ObjectId;
var postSchema = new Schema({
thread: ObjectId,
date: {type: Date, default: Date.now},
author: {type: String, default: 'Anon'},
post: String
});
module.exports = mongoose.model('Post', postSchema);
In the router part its used like this
exports.show = (function(req, res) {
Thread.findOne({title: req.params.title}, function(error, thread) {
var posts = Post.find({thread: thread._id}, function(error, posts) {
res.send([{thread: thread, posts: posts}]);
});
})
});
And in the app.js there is
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/norum');
I dont understand why these two have different approach and which one is the better one and why? Can Anyone please help me. One thing that I have observed is that the second approach is the one most used. SO please help me as to which one is a better approach.
I know this is mainly concerned regarding creation of the schemes in Mongodb, and so the once method looks little better. But still I am not at all sure. Please help.
Basically, in the first approach - it mearly shows you what you can do with the mongoose. It presumes that somewhere you were opening a connection to the database (presumably a few string of code back). Then it listens to the event and does all the job later. It's only there to show you what you can do.
For intance, this creates a mongoose model (it doesnt rely on the database connection being open) - hence it could be included from a separate file with ease and generally be written as a module as it is in the second approach
var teamSchema = new mongoose.Schema({
country: String,
GroupName: String
});
var Team = db.model('Team', teamSchema);
Later on in the first approach you close the connection to the database, but thats not the thing you would want to do in the real application. You have a connection pool, and use it to frequently query the database, closing the connection is only needed when you plan to stop the application from running.
Team.find({'GroupName':gname}, function (err, teams) {
if(err){
onErr(err,callback);
}else{
mongoose.connection.close();
console.log(teams);
callback("",teams);
}
First line - you perform find on the database, if no err was returned - you close the connection, log the results, etc..
Anyway, to sum up - first approach is generally a show-off, second - is what its like in a real world - where you separate logic, make models reusable and includable, where you have router logic

mongoose find().all()

Windows 7 x64, node.js, mongoose from npm.
var sys = require('util');
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:28960/test_mongoose');
var Schema = mongoose.Schema;
//Model
var UserSchema = new Schema({
username : String,
uid : String,
messaged_on : Date
});
mongoose.model('User', UserSchema);
var User = mongoose.model('User');
// create a new user
var user = new User({
uid : '54321',
username : 'Bob',
messaged_on : Date.now()
});
user.save( function (err) {
if (err)
return;
console.log('Saved');
User.find().all(function(user) {
console.log('beep');
});
});
Connection to mongod accepted, database 'test_mongoose' created.
Console print 'Saved', but 'beep' not.
I am newbie in mongoose, but, what is a prolem? Why do User.find().add() not call function back (user)?
Sorry for my bad english.
Maybe is it normal?
You should be calling User.find(... instead of User.find().all(.... The all method invokes the $all operator which is only used when matching arrays.

Resources