In the module mongoskin when getting the database object mongoskin does this in a sync fashion, hence the code:
var db = mongoskin.db(url, {
native_parser: true
});
var myCollection = db.collection('myCollection');
I am curious, how do they achieve this? I've been looking at the mongoskin code I however do not fully understand it.
And here, you can see mongoskin simplifys it :
https://github.com/kissjs/node-mongoskin#dbcollection-callback origin vs. mongoskin
Anyone know how mongoskin turned async code into sync fashion?
They say it in the beginning of the readme:
We make some common use functions in promise mode, we call it SkinClass of a normal Class. And the API is almost same with official API.
db.collection('myCollection'); returns SkinCollection - a wrapper for native Collection, which will use Collection when it is available.
The magic lives here: https://github.com/kissjs/node-mongoskin/blob/master/lib/utils.js
Related
I've a mongodb collection which has more than 20 million collection.
db.collection.find({ 'attr.type': new RegExp('automotive snow' 'i') }).limit(10);
Above mongo shell query returns the results as expected, But implementing the same in a node.js application it doesn't seem to work right. I can't really figure out the reason.
Sample node.js code
db.collection.find({ 'attr.type': new RegExp('automotive snow' 'i') }, function(err, docs) {
console.log(docs); // returns undefined
});
I use mongojs module, Tried native mongodb module as well but the results seemed to be the same hence decided to use mongojs module.
Does anyone know what the issue is?
Is there a way to use multiple databases with a single connection to mongodb? I've found this:
https://mongodb.github.io/node-mongodb-native/api-generated/mongoclient.html#open
but as best I can tell those docs are old as there does not appear to be an open method on the MongoClient? Do you actually need to establish multiple connections?
Thanks!
Found it:
http://mongodb.github.io/node-mongodb-native/2.0/api/Db.html#db
Here is their example
var MongoClient = require('mongodb').MongoClient,
test = require('assert');
MongoClient.connect('mongodb://localhost:27017/test', function(err, db) {
test.equal(null, err);
// Reference a different database sharing the same connections
// for the data transfer
var secondDb = db.db("integration_tests_2");
...
It is synchronous. Seems strange to me this method doesn't have the word "use" in it. Also seems strange it belongs to the db class. db.db('other_db').. a bit obscure. Did some tests, seems to work, so I'll mark this as the answer for anyone else that ends up here.
When I first used MongoDB I managed to connect successfully, however then I wanted to carry out the most basic query such as:
db.users.find()
I got an error saying TypeError: Cannot read property 'find' of undefined
Basically meaning I cannot use a collection as a property to the object db.
So i tried this:
var user_col = db.collection('users');
user.col.find();
which works absolutely fine.
Over the last few days I have kept having to look up other ways of doing things as the standard documented way doesn't seem to work. Just now I wanted to get the total users on the app, so like it says in the documentation I should do this:
var count = db.runCommand( { count: 'users' } );
console.log(count);
however this gave the error:
TypeError: undefined is not a function
Is there a problem with MongoDB you have seen like this before or am I just being stupid? I do not want to have to keep finding other, less efficient ways of doing things so finally I ask here what is going on.
Thank you.
It appears you are confusing the Mongo shell API with the node.js native driver API. While both are JavaScript, the shell is sync while node.js is async so they're totally different.
I installed sqlite3 with npm
npm install sqlite3 --save
I have written some basic functions that I would like to be performed synchronously rather then with async.
for instance I would like to get column names in one function and the row count in another.
I would like to simply return these values. currently I am using a callback like so
d.cinfo = function(table, callback){
var o = {};
db.each("PRAGMA table_info(" + table + ")", function(err, col){
o[col.name] = col.type;
}, function(){
if(typeof callback == 'function') callback(o);
});
}
d is an object which is later exposed
however Id like to return the values
d.cinfo = function(table, callback){
var o = {};
db.each("PRAGMA table_info(" + table + ")", function(err, col){
o[col.name] = col.type;
}, function(){
return o;
});
}
is there a way I can achieve this. I found documentation saying it was possible but then I learned that it was outdated and im not sure its meant for the same api
I have implemented bluebird however Promise.promisifyAll(middleware) returns and error "Object # has no method .then() anyone know what im doing wrong
I've come across a problem like this and many others while using Express and it really drives me crazy where I just can't avoid callback hells.
Some of the possible solutions can be:
Using the same old event driven style. Instead of calling nested functions, emit events for them. But I'm assuming you wouldn't like that very much, but that atleast gets rid of the nested callbacks.
There's a npm module called bluebird that allows you to extend existing modules with promises. (Using promisifyAll). So promises will still trim down the code and you'll have much cleaner code than you had before using promises.
If you don't mind switching frameworks, you can try KoaJS that allows you to yield(fun stuff from ECS 6) functions using generator functions(another cool feature). You can have more reading about this here.
So the above code can be re-written like:
var rows = yield db.each() //or something like that
this is an amazing feature but the drawback is that you have to use unstable versions of node (0.11.x). We also faced some issues setting up https using 0.11.x and had to downgrade to 0.10.x (we're not using koa either)
If there are only a few places where you need to do such kind of stuff, I would recommend using bluebird, but if you're tired of having lots of callbacks in your code, better go for Koa, although I've already mentioned you the tradeoffs.
I managed to create a module to handle all the database call. It uses this lib: https://github.com/developmentseed/node-sqlite3
My issues are the following.
Everytime I make a call, I need to make sure the database exist, and if not to create it.
Plus, as all the calls are asynchronous, I end up having loads of functions in functions in callbacks ... etc.
It pretty much looks like this:
getUsers : function (callback){
var _aUsers = [];
var that = this;
this._setupDb(function(){
var db = that.db;
db.all("SELECT * FROM t_client", function(err, rows) {
rows.forEach(function (row) {
_aUsers.push({"cli_id":row.id,"cli_name":row.cli_name,"cli_path":row.cli_path});
});
callback(_aUsers);
});
});
},
So, is there any way I can export my module only when the database is ready and fully created if it does not exist yet?
Does anyone see a way around the "asynchronous" issue?
You could also try using promises or fibers ...
I don't think so. If you make it synchronous, you are taking away the advantage. Javascript functions are meant to be that way. Such a situation is referred to as callback hell. If you are facing problems managing callbacks then you can use these libraries :
underscore
async
See these guides to understand basics of asynchronous programming
Node.js: Style and structure
Using underscore.js managing-callback-spaghetti-in-nodejs
Using async.js node-js-async-programming