I'm just learning how use mongoDb and I get confused by the documentation about the Collection.remove() method.
In first place, I tried to follow this doc:
http://docs.mongodb.org/manual/reference/method/db.collection.remove/
But I got the message Error: Cannot use a writeConcern without a provided callback, so I searchd why and I found this documentation then: http://mongodb.github.io/node-mongodb-native/api-generated/collection.html
In the first one there are two args, in the second there are three.
Then I did a console.log((mongodb.Collection(db, 'user').remove).toString());
And I got function remove(selector, options, callback)...
So now I just don't understand what's going on here, Is there different kind of Collection class? I whish to understand which documentation I should follow.
It seems like you just have to provide a callback-function:
Collection.remove(function(err, removedCount) {
//your next actions
});
From documentation:
[callback] (function) – must be provided if you performing a remove with a writeconcern
Related
I'm working on a node.js app that uses MongoDB and I read this from the docs:
db.collection
Fetch a specific collection (containing the actual collection information). If the application does not use strict mode you can can use it without a callback in the following way.
var collection = db.collection('mycollection');
First of all, what 'strict mode' is the doc referring to?
Also, is it a bad practice to grab the collection in this fashion? Without the callback, wouldn't I lose the ability to capture a potential connection error when trying to select the right collection?
db.collection('some_collection', function(err, collection) {
// query goes here
});
http://mongodb.github.io/node-mongodb-native/api-generated/db.html#collection
strict, (Boolean, default:false) returns an error if the collection
does not exist
Right there in the documentation.
That is there so your application may not create new collections itself and can only reference what has been created before. Hence the need for the callback, in order to trap the error.
It might be referring to Javascript's strict mode instead of a Mongo specific feature. strict mode enables some optional but backwards incompatible changes in the Javascript language that help catch some bugs:
What does "use strict" do in JavaScript, and what is the reasoning behind it?
I'm using Node with postgresql. I'm trying to do a knex query to the bd.
Why this query doesn't work without the then() call?
knex('test').insert(User1).then();
it's because the framework expects you to either fulfill the promise or to invoke any other provided output interfaces
to chain the promise output is one of the cleaner ways to end the query building step, see this little example, hope it helps.
I think it's expected behavior.
I recently realized that DocumentDB supports stand alone update operations via ReplaceDocumentAsync.
I've replaced the Upsert operation below with the Replace operation.
var result = _client
.UpsertDocumentAsync(_collectionUri, docObject)
.Result;
So this is now:
var result = _client
.ReplaceDocumentAsnyc(_collectionUri, docObject)
.Result;
However, now I get the exception:
Microsoft.Azure.Documents.BadRequestException : ResourceType Document is unexpected.
ActivityId: b1b2fd71-3029-4d0d-bd5d-87d8d0a2fc95
No idea why, upsert and replace are of the same vein and the object is the same that worked for upsert, so I would expect it to work without problems.
All help appreciated.
Thanks
Update: Have tried to implement this using the SelfLink approach, and it works for Replace, but selflink does not work with Upsert. The behavior is quite confusing. I don't like that I have to build a self link in code using string concatenation.
I'm afraid that building the selflink with string concatenation is your only option here because ReplaceDocument(...) requires a link to the document. You show a link to the collection in your example. It won't suck the id out and find the document as you might wish.
The NPM module, documentdb-utils, has library functions for building these links but it's just using string concatenation. I have seen an equivalent library for .NET but I can't remember where. Maybe it was in an Azure example or even in the SDK now.
You can build a document link for a replace using the UriFactory helper class:
var result = _client
.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(databaseId, collectionId, docObject.Id), docObject)
.Result;
Unfortunately it's not very intuitive, as Larry has already pointed out, but a replace expects a document to already be there, while an upsert is what it says on the tin. Two different use-cases, I would say.
In order to update a document, you need to provide the Collection Uri. If you provide the Document Uri it returns the following:
ResourceType Document is unexpected.
Maybe the _collectionUri is a Document Uri, the assignment should look like this:
_collectionUri = UriFactory.CreateDocumentCollectionUri(DatabaseName, CollectionName);
As you know, in mongoose, we can remove all users with age 30 like this:
User.find({age: 30}).remove(callback);
Now, replace find() with findOne(), and I think it should remove only 1 user:
User.findOne({age: 30}).remove(callback);
oh, not as I expected, the code above also remove ALL instead of ONE
So, why findOne().remove() remove ALL instead of ONE? Is that a bug or a feature and why?
Thanks in advance!
P/S: I know findOneAndRemove() would remove one user for me, but in this question I want to understand findOne().remove()
I have reported this question to mongoose team, and got a reply:
https://github.com/LearnBoost/mongoose/issues/1851#issuecomment-31355346
Here's the message from aheckmann
"that's a good catch. findOne just sets the command name to run, remove() changes it back to a rice command but no limit was ever set. We should probably change that in 3.9 so that findOne sets
the limit as well."
Both find and findOne returns mongoose Query objects which only contains information about the model and the specified query. It's not taking into account findOne which is applied first in the callback. What you expect to happen is to have options be set like this User.findOne({age: 30}, null, {limit: 1}).remove() as this would only remove one and you could argue that this is a bug, but that depends on the usage. Like you have already pointed out, the right way to go is to use findOneAndRemove().
I'm kind of a noob but wouldn't you need to put your remove in the callback because this is an asynchronous function? Try something like:
User.findOne({age: 30}, function(err, user){
user.remove()
})
There are two different methods to obtain a reference to a MongoDB collection - both of them are used throughout the official documentation.
There is
var mycollection = db.collection('mycollection)'
and there is
db.collection('mycollection', function(err, collection){
//use collection
}
I tend to use the second one because it is consistent with "db.createCollecion(collection, callback)"
What is the difference between these methods?
Is there any database interaction when using these methods?
If you look at the code for Database, currently around line 456, you'll see that the only difference between the two in the way you've used them is how the collection object is returned. If you specify a callback, then it's returned that way, otherwise, it's returned as the value to the function. If you set the options however and specifically the option strict to true, you need to use the callback. When strict is set to true, the collection is verified before continuing (asynchronously).
Given that collections can be created dynamically (and usually are upon first use), there often isn't need to use strict mode.
So, it's really matter of personal coding preference otherwise. There is normally no activity to the database when creating a Collection object via: db.collection('collectionname') with the exception I mentioned above.