I'm trying to drop a non existant collection and I get the following error:
MongoError: ns not found.
In a similar question, there is a link to the mongo code which shows that this is the expected behaviour:
MongoError: ns not found when try to drop collection
However, according to the mongo documentation, this method should return false if the collection does not exists:
https://docs.mongodb.com/manual/reference/method/db.collection.drop/#db.collection.drop
What am I missing?
Server version - 3.6.5, mongodb client (javascript) - 3.0.21
The commands I used:
await mongodb.collection('colname').drop()
and
mongodb.collection('colname').drop((err, res) => {
console.log('err: ' + err + ', res: ' + res) // doesn't get called
})
You link refers to the command interface of the mongo client. It uses javascript but is an application that has its own REPL. The documentaion is correct.
The command you are using is from the official mongodb node package. The behavior of these commands are different than those on the mongo client. The documentation concerning your usage is here: http://mongodb.github.io/node-mongodb-native/3.0/api/Collection.html#drop
BTW, the first parameter is an option object, the second would be the callback.
The callback you provide is only called on a successful mongodb query. When the collection does not exist (like in this case), the callback is not executed. But this function returns a promise, which can be used to handle any error:
mongodb.collection('colname').drop().then(function () {
// success
}).catch(function () {
// error handling
})
Related
I have got a serverless db on atlas (https://www.mongodb.com/serverless). I used the connection string recommended by ATLAS:
mongodb+srv://<username>:<password>#xyz.esxbh.mongodb.net/myFirstDatabase?retryWrites=true&w=majority
however as soon as i try to create a record, i get the following error:
{"errorType":"Runtime.UnhandledPromiseRejection","errorMessage":"MongoParseError: Text record must only set `authSource` or `replicaSet`","reason":{"errorType":"MongoParseError","errorMessage":"Text record must only set `authSource` or `replicaSet`","name":"MongoParseError","stack":["MongoParseError: Text record must only set `authSource` or `replicaSet`","
I don't think that the connection string is correct, on the other hand the dns entry for the server does reply with 2 servers.
I tried dropping the '+srv' part, however in that case the save function from mongoose just hangs forever timing out the lambda function.
I could not find any similar problem on google.
The TXT entry record from the dns server shows:
"TXT "authSource=admin&loadBalanced=true"
How have you configured the serverless database to work?
The code that generates the error depends on mongoose and is as follows:
try {
const customer = new Customer(cust);
console.log('new cusotmer created');
const returnedCustomer = await customer.save();
console.log(returnedCustomer);
return serverResponse(200, returnedCustomer);
} catch(err){
console.log(err);
return errorHandler(500, err)
}
It seems that the connection to the database is fine:
try {
await dbTools.connectMongoose();
console.log('*** connected ***');
} catch(err){
console.log('error when connecting');
return errorHandler(500, err);
}
Now, looking at the source code, nothing really too complicated:
if (Object.keys(record).some(key => key !== 'authSource' && key !== 'replicaSet')) {
return callback(
new MongoParseError('Text record must only set `authSource` or `replicaSet`')
);
}
I am now really struggling to understand what's wrong as authSource seems to be present in the TXT record.
Upgrading mongoose to the latest version worked for me in Nodejs.
Remove "mongoose" from package.json.
Reinstall "npm i mongoose"
"mongoose version 6.0.5" should work.
Worked on 10-Sep-2021
For anyone still experiencing this in 2022, here is an answer from a MongoDB employee (at the bottom). It's a native Node.js driver issue (nothing to do with AWS lambda specifically), which will waterfall to all ODM implementations that implement the native driver.
https://www.mongodb.com/community/forums/t/atlas-serverless-and-dns-txt-record/117967/8
According to Zia Ullah's answer to this same question, this is fixed by Mongoose 6.0.5.
Hopefully someone can help me solve what I am sure is a rookie mistake.
I am trying to adapt an authentication app originally based on mongodb, to work with sequelize\MSSQL instead, but getting tied up in knots with trying to blend a callback-based working example with
seqeulize's promised based approach.
Both MongoDb\Sequelize offer a findOne() method.
Original (working) code referencing MongoDb collection:
module.exports.getUserByUsername = function(username,callback){
var query = {username: username};
User.findOne(query,callback);
}
The callback in this case is from a separate calling module and is the standard verify password of passport.js's local-strategy.
Since the sequelize findOne() method expects a where clause I had hoped the following would be an out of the box solution:
module.exports.getUserByUsername = function(username,callback){
var query = {where: {username: username}};
User.findOne(query,callback);
}
This outputs a functional query into the console.log, but the callback doesn't fire, so the page hangs.
Looking at the respective API docs it appears that sequelize findOne() is exclusively promise based whereas MongoDb findOne() returns a promise only if where a callback function is not passed to the findOne() method, otherwise flow is handed to the callback when one is provided as is the case with the working example.
I tried the following adaptation to work with a sequelize promise (and quite a number of permutations thereof calling the callback function within the .then() clause etc)., but all fail with a hanging page: :
module.exports.getUserByUsername = function(username,callback){
var query = {where: {username: username}};
return User.findOne(query).then(user => {
console.log(user.get({ plain: true }));
return user.dataValues;
//callback(user.dataValues)
}).finally(() => {
console.log('done!')
});
}
The console.log(user.get()) spools out the correct details showing the database query executed correctly returning the required user data, so I feel that I'm very near to finding the right syntax to delivering this back to the passport callback.
Any help would be much appreciated!
Add raw property to true like this, and you can get the user object
User.findOne({ where : {username:username}, raw: true}).then( user => {
return user
})
When receiving JSON data via websockets, I'm trying to feed this data into a mongodb within meteor. I'm getting the JSON data fine, but when trying to find whether the data already exists in the database, I keep getting the error: "[ 'Parse error: Can\'t wait without a fiber' ]'.
binance.websockets.miniTicker(markets => {
//we've got the live information from binance
if (db.Coins.find({}).count() === 0) {
//if there's nothing in the database right now
markets.forEach(function(coin) {
//for each coin in the JSON file, create a new document
db.Coins.insert(coin);
});
}
});
Can anyone point me in the right direction to get this cleared up?
Many thanks,
Rufus
You execute a mongo operation within an async function's callback. This callback is not bound to the running fiber anymore. In order to connect the callback to a fiber you need to use Meteor.bindEnvironment which binds the fiber to the callback.
binance.websockets.miniTicker(Meteor.bindEnvironment((markets) => {
//we've got the live information from binance
if (db.Coins.find({}).count() === 0) {
//if there's nothing in the database right now
markets.forEach(function(coin) {
//for each coin in the JSON file, create a new document
db.Coins.insert(coin);
});
}
}));
You should not require to bind to the function within the forEach as they are not async.
Related posts on SO:
Meteor.Collection with Meteor.bindEnvironment
Meteor: Calling an asynchronous function inside a Meteor.method and returning the result
Meteor wrapAsync or bindEnvironment without standard callback signature
What's going on with Meteor and Fibers/bindEnvironment()?
I'm working on an application using Meteor and MongoDB where I'm attempting use nested callbacks to access a newly inserted document as seen below. However I keep getting an error where there is no matching document in the database even though I'm in the successful callback of the insert statement. I'm not sure as to why Mongo can't find the document I just inserted. I understand that the methods are asynchronous, but I assumed that the callback would allow me to access the newly inserted document once the find function returns. I attempted to place the find outside of the insert statement with its own callback and got the same error.
I've attached the error message as well. Any help on this matter would be greatly appreciated!
insertEntryForm.call(entryFormObj, (error, result) => {
if (error) {
console.log(error);
toastr['error'](error.reason);
}
else {
toastr['success']("Entry form created!");
EntryForms.find({_id: result}, function(err, res) {
console.log(res);
});
}
}
);
From the documentation and the examples provided by Inserting and updating - MongoDB the second argument for the insert callback is the object inserted and in your find you're looking for a document with result , it should be result._id , so this should work :
EntryForms.find({_id: result._id}, function(err, res) {
Turns out the issue had to do with the way in which I was publishing/subscribing to my object within Meteor. I registered my subscription in my router.js file and was then able to access my collection as expected. Chalk this one up to my small experience with Meteor.
I am encountering a weird issue here...
After I seem to successfully insert some data into my db.collection I cant seem to get it to reflect using db.collection.find().fetch().
Find below the code I insert into my chrome console:
merchantReviews.insert({merchantScore: "5.5"}, function() {
console.log("Review value successfully inserted");
});
This yields:
"9sd5787kj7dsd98ycnd"
Review value successfully inserted
I think returned value "9sd5787kj7dsd98ycnd" is an indication of a successful db collection insert. Then when I run:
merchantReviews.find().fetch()
I get:
[]
Can anyone tell me what is going on here?
Looking forward to your help.
There are two possibilities here: either the insert fails on the server even though it passes on the client, or you haven't subscribed to your collection.
In case the insert fails on server (most likely due to insufficient permissions, if you have removed the insecure package but have not declared any collection.allow rules), the client code still returns the intended insert ID (in your case, "9sd5787kj7dsd98ycnd"). The callback is called once the server has confirmed that the insert has either failed or succeeded. If it has failed, the callback is called with a single error argument. To catch this, you can instead insert the document like this:
merchantReviews.insert({merchantScore: "5.5"}, function(error) {
if (error) {
console.error(error);
} else {
console.log("Review value successfully inserted");
}
});
If this still logs successful insert, then you haven't subscribed to the collection, and you have removed the autopublish package. You can read about Meteor publish-subscribe system here. Basically, you have to publish the collection in server-side code:
Meteor.publish('reviews', function () {
return merchantReviews.find();
});
And in server code (or your js console) you need to subscribe to the collection with Meteor.subscribe('reviews'). Now calling merchantReviews.find().fetch() should return all documents in the collection.