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
Related
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 .
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
}
});
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.
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);
});
});
I am experimenting with Meteor.js and looking for a full-text search engine that can run on Meteor/MongoDB server. It seems that Meteor has not developed this feature.
I wonder if there is an existing solution for adding full-text search to Meteor app.
The only thing I can find is MongoLantern, which has node.js API. How should I go about adding MongoLantern to my Meteor app?
MongoDB 2.4 will have a full text search in it. Guide can be found here.
If you are prepared to run the development releases you can download MongoDB 2.3 now - it contains text search.
Update: MongoDB 2.4 has been released. Text search is described as Beta.
The guide for text search is here and the mongod must be run like this
mongod --setParameter textSearchEnabled=true
Take a look at http://lunrjs.com/. That might also help in getting the near-instant performance of real Meteor app.
You might want to have a look at:
https://github.com/Crenshinibon/spomet
It's a Meteor native package to provide full-text search. It has an easy to include search-box with autocompletion.
You can read a tutorial about an extended example application here:
http://shiggyenterprises.wordpress.com/2013/09/28/developing-a-full-text-search-enabled-meteor-app/
There is also another way to implement a solution with Meteor. It's Search Source.
It's a kind of typeahead but without the UI part. It exposes a reactive datasource where you can use it to build the UI with Blaze as you need.
Here's a demo app: https://instant-search-demo.meteor.com/
Above app is an instant search app to search Meteor packages. How it can build with search source is documented in this article
In brief this is how search source works:
In client, create a source
var options = {
keepHistory: 1000 * 60 * 5,
localSearch: true
};
var fields = ['packageName', 'description'];
PackageSearch = new SearchSource('packages', fields, options);
Then in the server define the search source
SearchSource.defineSource('packages', function(searchText, options) {
var options = {sort: {isoScore: -1}, limit: 20};
if(searchText) {
var regExp = buildRegExp(searchText);
var selector = {packageName: regExp, description: regExp};
return Packages.find(selector, options).fetch();
} else {
return Packages.find({}, options).fetch();
}
});
function buildRegExp(searchText) {
// this is dumb implementation
var parts = searchText.trim().split(' ');
return new RegExp("(" + parts.join('|') + ")", "ig");
}
Now get the data source and render it
Template.searchResult.helpers({
getPackages: function() {
return PackageSearch.getData({
transform: function(matchText, regExp) {
return matchText.replace(regExp, "<b>$&</b>")
},
sort: {isoScore: -1}
});
}
});
Finally do the search
PackageSearch.search("the text to search");
You can learn more about how each of the above works with from the documentation.