how to implelement custom mongodb driver - mongodb

I using mongodb in my poject and interesting how to implement simple mongodb driver which will allow to run mongodb command like in a shell form. Just writing command in javascript and pushing it to mongodb, then geting result and deserializing it.

Substitute your connection string in the code below.
While it would be extremely dangerous to provide this generally speaking (as it allows any command to execute), just call the eval function on the instance of the database that's returned.
This code is use the JavaScript/NodeJS driver:
var
mongodb = require('mongodb'),
MongoClient = mongodb.MongoClient
;
MongoClient.connect("mongodb://localhost:27017/default?w=1",
function (err, db) {
db.eval("db.version()", null, {noLock: true}, function(err, results) {
console.log(results);
});
});

Related

MongoDb toArray

I am using mongodb and in the following code I am using mongodb find().toArray(), but it is giving me the error "Cannot read property 'toArray' of undefined"
req.activedb.collection('items').find().toArray(function (err, data) {
//...some code
})
whereas when I am using findOne(), then it is working properly.
req.activedb.collection('items').findOne(function (err, records) {
console.log(err, records); //Getting a single record here
})
req.activedb is my current db instance
Can you please tell me, what is missing here ?
I have resolved this issue.
Actually I was using mongoose to connect with my db, so it does not support find(). So now I am connecting to the db using new Db() method and it is working properly.
I have run belows command its work for me.
posts is nothing but collection.
db.posts.find().toArray();
You might be, you are making mistake in syntax .

MongoDB Defaulting to Strict Mode

We have a nodejs + mongodb application that has been running in production for several years, and in development on multiple machines. On just one developer's machine, I'm seeing the error
MongoError: collection already exists
Researching this error indicates that this will occur when trying to create an existing collection only if the collection is in strict mode. We don't invoke mongo's strict mode anywhere in our application, and we can only reproduce this error on one machine.
Code which causes this error is as follows:
var mongo = require('mongodb');
mongo.MongoClient.connect(config.mongoConnectionString, {w:1}, function(err, db) {
db.createCollection('accounts', function(err, collection) {
// "err" here is the error message.
});
});
Is there a way to override mongo's default strict: false value? Is there a global configuration option that causes strict mode to be turned on? I would rather not modify the code to specify strict: false for every collection just to enable a single developer. The developer is running mongo v3.2
You can disable 'strict' mode by using this
var mongo = require('mongodb');
mongo.MongoClient.connect(config.mongoConnectionString, {w:1}, function(err, db) {
db.createCollection('accounts', {strict:false}, function(err, collection) {
// "err" here is the error message.
});
});
you can read more about this from here

Meteor.subscribe on server side

I want to create a backend service which monitors a mongodb collection for new entries. As those are being created, I wish to run processing and update them.
I thought doing so with a Meteor service/app would be a wise idea because Meteor uses 'oplog tailing' which seems ideal for this purpose (I'd rather avoid polling if possible).
As such, I figured creating a minimal server-side-only app should solve it.
So basically, I need something along these lines:
if (Meteor.isServer) {
MyCollection = new Mongo.Collection('myCollection');
Meteor.publish('myCollectionPub', function () {
return MyCollection.find({ some: criteria... });
}
// is there such a thing?
Meteor.serverSideSubscribe('MyCollectionPub',
function (newDocs) {
// process/update newDocs
});
}
According to the Meteor docs, I cannot use Meteor.subscribe() on the server (and indeed it crashes if I try).
Question is:
Are there ways of 'subscribing' to collection updates on the server?
The PeerLibrary server-autorun package (along with it's dependant, reactive-mongo) will provide you with easy server-side observation of collections.
An alternative to #tarmes suggestion is the collection-hooks package, however as pointed out by David Weldon, it will only trigger in instance it is run in:
https://github.com/matb33/meteor-collection-hooks
MyCollection.after.insert(function (userId, doc) {
// ...
});
If you need it to run even when another instance makes a change in the mongo database, you can observe a cursor that is returned from your collection:
MyCollection.find({created_at : {$gt: some_current_time}}).observe({
added: function(item) {
// Alert code
}
});

In Meteor, a MongoDB update is not seen in the Mongo shell

This is a very odd problem.
I am running a cursor.observe() in a Tracker.autorun(), but the changes are only occurring when I refresh the page. Here is the imporant code:
Client Side
Tracker.autorun(function (){
var initializing = true;
Links.find().observe({
added: function(doc){
var parents = Links.find({stacks: {$exists: true, $not: {$size: 0}}});
//Find the parent of this item with a stack array
if(!initializing){
_.each(parents.fetch(), function(parentDoc){
_.each(parentDoc.stacks, function (stackId){
//The troublesome server call
Meteor.call("addLinksFromDirToStack",
stackId, parentDoc.shared[0].id, parentDoc._id);
});
});
}
initializing = false;
}
});
});
Server Side
Meteor.methods({
addLinksFromDirToStack: function(stackId, userId, dirId){
var stack = Stacks.findOne(stackId);
if (stack){
var webArray = stack.webArray;
webArrayFiller(dirId, webArray);
Stacks.update(stackId, {$set: {webArray: webArray}});
Stacks.update(stackId, {$addToSet: {users: userId}});
}
// NOTE: IF I QUERY THE STACKS COLLECTION HERE, I SEE THE CHANGES
}
});
webArrayFiller = function(dirId, webArray){
//Update array
}
As commented above, If I query the Stacks collection directly after my update, the changes are reflected in the database. However, querying from the Mongo Shell, I still see the old Stack, without the update. And this is case on the client side, where the changes should be displayed.
I have tried a Meteor Reset to no avail. Any help would be much appreciated.
I figured out why it wasn't working.
I wasn't publishing every field of the Stacks collection. In particular, not the users field. Thus when I would attempt to change the collection with this line, it would fail:
Stacks.update(stackId, {$addToSet: {users: userId}});
However, Minimongo recognized the change, and so my queries would falsely show me I had succeeded. Once the server rejected the update, it would also reject the line directly above, making both changes not occur. Apparently, some find MongoDB's lack of error messages in failed transactions troublesome. It definitely made this error hard to find.
The solution was to wrap the server side code in a if (Meteor.isServer) so that it would only be run on the server side. An unfortunate consequence is that values cannot easily be returned from these calls, due to asynchronicity, but there are workarounds for that.

What's the easiest way to store a large object in Meteor using GridFS?

I'm trying to backup a Lunr Index to Mongo (daily), and because it's running around 13MB, I'm triggering MongoError: document is larger than capped size errors. I'd like to use GridFS to get around the problem, but I'm having a heck of a time getting it to click.
In the simplest terms: Within Meteor, I'd like to save a 13MB JSON object to MongoDB using GridFS, and then be able to retrieve it when necessary -- all only on the server.
I've gone through the File-Collection and CollectionFS docs, and they seem far too complicated for what I'm trying to accomplish, and don't seem to address simply storing the contents of a variable. (Or, more likely, they do, and I'm just missing it.)
Here's what I'd like to do, in pseudo-code:
Backup = new GridFSCollection('backup');
var backupdata = (serialized search index data object);
Backup.insert({name:'searchindex', data:backupdata, date:new Date().getTime()});
var retrieved = Backup.findOne({name:'searchindex'});
Any suggestions?
var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;
var GridStore = MongoInternals.NpmModule.GridStore;
var largedata = new GridStore(db,'name','w'); //to write
largedata.open(function(error,gs){
if (error) return;
gs.write('somebigdata',function(error,done){
if (error) return;
largedata.close();
})
});
var largedata = new GridStore(db,'name','r'); //to read data
largedata.open(function(error,gs){
if (error) return;
gs.read(function(error,result){
if (error) return;
//then do something with the result
largedata.close();
})
});
explanation
First you need the db object, which can be exposed via the MongoInternals https://github.com/meteor/meteor/tree/devel/packages/mongo
Second, you need the GridStore object, you get it from the MongoInternals as well
Then you can create a write or read object and follow the API http://mongodb.github.io/node-mongodb-native/1.4/markdown-docs/gridfs.html
The mongo used by Meteor is 1.3.x whereas the latest node mongodb native driver is 2.x.x http://mongodb.github.io/node-mongodb-native/2.0/api-docs/
So the API may change in the future. Currently, you need to do open and close and the callback are all async, you may want to wrap them with Meteor.wrapAsync (may not work on largedata.open), Future or Fiber