Can't create MongoDb connection with 2.2.10 Node.js driver - node.js

Trying to open connection (using mongodb native driver 2.2.10, and mongoose 4.6.3).
Getting exception:
must pass in valid bson parser
Looks like this is a connection.js line 55.
The same error occurs:
1. for `mongodb` client fails on `MongoClient.connect`.
2. for `mongoose` it fails on startup (before any code execution).
According to documentation I don't need to pass any value to bson options field.

I get the same error. Seems that from v2.2.0 it occurs when you do not close the connection, even if the value returned in Promise.
From docs updateOne method (focus on db.close()):
// Example of a simple updateOne operation using a Promise.
var MongoClient = require('mongodb').MongoClient,
test = require('assert');
MongoClient.connect('mongodb://localhost:27017/test', function(err, db) {
// Get the collection
var col = db.collection('update_one_with_promise');
col.updateOne({a:1}
, {$set: {a:2}}
, {upsert:true}).then(function(r) {
test.equal(1, r.matchedCount);
test.equal(1, r.upsertedCount);
// Finish up test
db.close();
});
});
I do not know why so did very uncomfortable with Promise to pass also the db.
I rolled back to v2.1.21

Related

Node.js MongoDB crashes on Client.close()

I am using latest Mongodb 3.5.7 with Node.js and Express,
What I do is I call an async function when an API is being called and the code is as following :
async function insert(data) {
try {
const connection = await client.connect();
db =client.db(dbName);
const insertion = await db.collection('inserts').insertOne(data);
//console.log(await client.close());
await console.log('finished waiting promises');
await client.close();
} catch (err) {
console.log(err.stack);
return Promise.reject('false');
}
return new Promise(resolve =>{
resolve();
})
}
`
In fact the first API Call works so well and successfully inserts the data into db , the issue starts with the second try which brings this error
I also tried promises in separated functions with every command ( connect - insert -close ) with call back promise and await for each one to be done.
As well tried calling connecting function which i created.then(setdbname).then(insert).then(closedb) ...
the options [servers] is not supported
the options [caseTranslate] is not supported
the options [dbName] is not supported
the options [credentials] is not supported
MongoError: topology was destroyed
at executeWriteOperation (C:\Users\raymo\Documents\Ticket\node_modules\mongodb\lib\core\topologies\replset.js:1188:21)
at ReplSet.insert (C:\Users\raymo\Documents\Ticket\node_modules\mongodb\lib\core\topologies\replset.js:1257:3)
at ReplSet.insert (C:\Users\raymo\Documents\Ticket\node_modules\mongodb\lib\topologies\topology_base.js:322:25)
at insertDocuments (C:\Users\raymo\Documents\Ticket\node_modules\mongodb\lib\operations\common_functions.js:259:19)
at InsertOneOperation.execute (C:\Users\raymo\Documents\Ticket\node_modules\mongodb\lib\operations\insert_one.js:26:5)
at C:\Users\raymo\Documents\Ticket\node_modules\mongodb\lib\operations\execute_operation.js:98:26
at new Promise (<anonymous>)
at executeOperation (C:\Users\raymo\Documents\Ticket\node_modules\mongodb\lib\operations\execute_operation.js:91:10)
at Collection.insertOne (C:\Users\raymo\Documents\Ticket\node_modules\mongodb\lib\collection.js:516:10)
at Object.insert (C:\Users\raymo\Documents\Ticket\routes\Handlers\DatabaseHandler.js:68:63)
as well I tried downgrading to mongo v. 3.4.0
I tried normal Callback functions and it works. but i need to upgrade and work with promises and await/async
Please suggest edits if my question is not clear.
client.close() closes the current db connection, including all the child db instances as stated in the documentation. This means that once you've called it, the current mongo client can no longer be used. You'd need to create an entirely new MongoClient and call connect() on it.
But - you should not do this, there's no need to manually create/close the connection for every database operation.
Just keep your connection instance after doing const connection = await client.connect(); and reuse/share it for your other operations. MongoClient already handles connection pooling for you.

Why mongoose opens two connections?

It's a simple file from mongoose quick guide
mongoose.js
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/Chat');
var userSchema = mongoose.Schema({
name: String
});
var User = mongoose.model('User', userSchema);
var user = new User({name: 'Andy'});
user.save(); // if i comment it mongoose will keep one connection
User.find({}, function(err, data) { console.log(data); }); // the same if i comment it
I tried to use db.once method, but effect the same.
Why mongoose opens the second connection in this case?
Mongoose uses native mongo driver underneath, and it in turn uses connection pooling - I believe the default is 5 connections (Check here).
So your mongoose connection will use up to 5 simultaneous connections when it has simultaneous requests.
And since both user.save and User.find are asynchronous, those will be done simultaneously. So what your "program" tells node:
1. Ok, you need to shoot a `save` request for this user.
2. Also, you need to fire this `find` request.
The node runtime then reads these, runs through the whole of your function (until a return). Then it looks at it's notes:
I was supposed to call this save
I also need to call this find
Hey, mongo native driver (which is written in C++) - here are two tasks for you!
and then the mongo driver fires the first request. And it sees it is allowed to open more connections then one, so it does, and fires the second request too, without waiting for the first to finish.
If you called the find within a callback to save, it would be sequential, and the driver would probably reuse the connection it already had.
Example:
// open the first connection
user.save(function(err) {
if (err) {
console.log('I always do this super boring error check:', err);
return;
}
// Now that the first request is done, we fire the second one, and
// we probably end up reusing the connection.
User.find(/*...*/);
});
Or similar with promises:
user.save().exec().then(function(){
return User.find(query);
})
.then(function(users) {
console.log(users);
})
.catch(function(err) {
// if either fails, the error ends up here.
console.log(err);
});
By the way, you can tell mongoose to use only one connection if you need to, for some reason:
let connection = mongoose.createConnection(dbUrl, {server: {poolSize: 1}});
That would be the gist of it.
Read more on MongoLab blog and Mongoose website.

`TypeError: pool.getAll is not a function` when connecting to MongoDB

I am writing an API with Node and Express, and use MongoDB as the database.
It has worked for a long time now, but today when I wrote some changes to a model, the server won't start anymore. I originally thought that a recent code change caused it, but even if I stash my changes and reset to a working state, the error occurs.
This is the error:
TypeError: pool.getAll is not a function
at MongoCR.auth (/location/of/project/node_modules/mongodb/node_modules/mongodb-core/lib/auth/mongocr.js:56:26)
at Server.auth (/location/of/project/node_modules/mongodb/node_modules/mongodb-core/lib/topologies/server.js:1019:40)
at ReplSet.auth (/location/of/project/node_modules/mongodb/node_modules/mongodb-core/lib/topologies/replset.js:572:17)
at ReplSet.auth (/location/of/project/node_modules/mongodb/lib/replset.js:438:23)
at authenticate (/location/of/project/node_modules/mongodb/lib/db.js:1319:21)
at Db.authenticate (/location/of/project/node_modules/mongodb/lib/db.js:1356:44)
at /location/of/project/node_modules/mongodb/lib/mongo_client.js:414:25
at /location/of/project/node_modules/mongodb/lib/db.js:221:5
at connectHandler (/location/of/project/node_modules/mongodb/lib/replset.js:335:7)
at g (events.js:260:16)
If I comment out all database connections the app runs. I've tried changing database, but it does not work either. I found this and this question and answer, and double checked versions and that all db-calls have callback-methods. I've used the last argument as the callback for calls that affect one entry, and toArray(function(err, result){}) when there are multiple entries returned.
Mongo version is 2.6.3, and I use the Node-mongodb driver.
I connect with
var mongo = require('mongodb').MongoClient;
var url = process.env.MONGODB || 'mongodb://localhost:27017/test';
var myCollection;
mongo.connect(url, function(err, db) {
if(err) console.log(err);
myCollection = db.collection('myCollection');
});
Then I have methods for e.g. find:
myCollection.find({}).toArray(function(err, result){
// work with result
});
I'm lost - thanks in advance.

Why isn't my Q promise working?

I'm new to promises and Q, and I'm trying to convert a route that uses query in node-mysql. Here are excerpts from my code:
var Q = require('q');
// connection defined elsewhere
router.get('/', function(req, res) {
var query = Q.denodeify(connection.query);
var promise = query("-- query ommitted --", [req.user.id]);
promise.then(console.log, console.error);
});
I'm trying to convert this from an existing set up that doesn't use promises, so I know the connection is set up properly and the query is valid. Whenever I try to request this route, I get the same message in stderr:
[TypeError: Cannot read property 'connectionConfig' of undefined]
I don't know where it's coming from so I'm not sure how to find the full stacktrace. I also tried an alternate version of this code where I had my own function instead of console.log and console.error, but this function was never called and the same error appeared.
Updated answer:
You're probably losing the lexical scope to connection when you denodeify the query method.
Looking at the Q documentation it says this can be an issue:
If you are working with methods, instead of simple functions, you can easily run in to the usual problems where passing a method to another function—like Q.nfcall—"un-binds" the method from its owner.
To fix this try using Q.nbind instead:
var query = Q.nbind(connection.query, connection);
var promise = query("-- query ommitted --", [req.user.id]);
promise.then(console.log, console.error);
Original answer:
Looking at the node-mysql source, the only place connectionConfig is accessed is in Pool.js. So my guess would be that you've got an issue with how the pool is being configured.

Native driver find from Mongoose model not returning Cursor

I'm trying to execute a native MongoDB find query via the collection property of a Mongoose Model. I'm not supplying a callback so I expect the find to return a Cursor object, but it returns undefined instead. According to the Mongoose docs, the driver being used is accessible via YourModel.collection and if I switch to purely using the native driver code find does return a Cursor so I can't figure out what's going on.
Here's a code snippet that reproduces the problem:
var db = mongoose.connect('localhost', 'test');
var userSchema = new Schema({
username: String,
emailAddress: String
});
var User = mongoose.model('user', userSchema);
var cursor = User.collection.find({});
// cursor will be set to undefined
I've tried to step into the code with node-inspector, but it's not letting me. Any idea what I'm doing wrong?
The native driver methods are all proxied to run on the nextTick so return values from the driver are not returned.
Instead, you can pass a callback and the 2nd arg returned is the cursor.
User.collection.find({}, function (err, cursor) {
//
});
Curious why you need to bypass mongoose?

Resources