Open insinfo opened 3 years ago
Yes, insertOne
adds an _id
field if not specified. Why should it give you a problem?
this caused me a problem, because I do an insertion and then an update of the same map in different collections, the first collection being a history of changes, and the second collection is the main one, but when I go to save in the second collection the error is due to that the first insert modifies the Map by putting an _id
maybe a solution for this would be the insertOne method to clone the Map so that it doesn't modify the original
Let's say that I have a map (myMap
):<String, dynamic>{'name': 'Isaque', 'familyName':'Neves}
Now I do the first insert in a collection, let's say history
.
As MongoDb requires an _id
field we have two ways of set the '_id':
1) before insertion create an ObjectId
(or any key you like) and assign it to the map:
var documentKey = ObjectId();
myMap['_id'] = documentKey;
await history.insertOne(myMap);
This way I have the map ready to be inserted in another collection (actual
)
await actual.insertOne(myMap);
If you need to update a document on actual
simply use the map you have
actual.replaceOne( where.id(myMap['_id']), myMap);
or
actual.replaceOne( where.id(documentKey), myMap);
2) I you do not want to insert manually the _id
field, insertOne
will do this for you.
The result is that myMap
will have the_id
set and you will be able to use it for the update.
So, filling the _id
field in insertOne
is intentional and useful.
Sorry, if I cannot help you anymore, but it is still unclear to me what you would like to do. If you could post an example without using your framework it could be useful.
Let us assume this situation:
var data = {"id":123456,"name":"Isaque", "age":36}
await db.collection('usedCoupons').insertOne(data);
await db.collection( 'coupons').replaceOne({'id':123456}, data);
final Map<String, dynamic> documentClone = {...document};
I do not know if it was a typo or not but beware that "id" and "_id" are two different things for mongoDb. MongoDb manages an "_id" field as unique key identifying a specific document inside a collection. This field must be present, mongo_dart adds it for you, if you omit it, but if the driver don't insert it the database server itself adds one. If it is not a typo, this is why your code is failing. The correct sequence should be:
var data = {"_id":123456,"name":"Isaque", "age":36}
If the map have been inserted in a collection it should contain an "_id" field.
await db.collection('usedCoupons').insertOne(data);
Now we insert the data map inside the "usedCoupons" collection with the same _id
as the "coupons" one.
As the _id
field is already present, it is not changed.
data['counter']++;
await db.collection( 'coupons').replaceOne({'_id':123456}, data);
No we can update the "coupons" collection using the unique identifier _id
.
Hope this can help.
I don't think you understand, I don't use the "_id" field, because I have my own method of generating unique "id", so I use an "id" field instead of "_id", my solution was to make a wrapper on top of the driver so that the insertion into the database is done without changing the Map passed via parameter, this was done easily through the spreed operator cloning the Map, by design I think the driver should not modify the instance of Map passed by parameter, it should clone the Map and modify the clone and not the original instance. my problem is not mongo putting the "_id" field, the problem is the driver modifying the Map instance passed via parameter
What I do not understand is why you do not use the _id
field if you already have an unique identifier.
The _id
field can be of any type you like, not necessarily an ObjectId
.
make the 'insertOne' and 'replaceOne' ... methods not modify the past Map, to prevent the error, "MongoError: The (immutable) field '_id' was found to have been altered"
I verified that the insertOne method was putting the "_id" in the Map which was causing me problem