Hi @aerabi and thanks for your reply! You’re right in that this doesn’t actually answer the original question, however I’ll try out Mongoose for my use-case and see if it provides a valid workaround. Thanks again! I’ll report back here.
Although I’d really like to know, if this functionality does actually exist with the native driver.
This issue has nothing to do with the mongodb driver but has everything to do with JS type checking. You might be using TypeScript rather than native JS.
Actually, it is has everything to do with the way you are coding your JS function
deleteDocumentWithId
When you declare (id : ObjectId) you are asking JS to make sure the function is called only with ObjectId. You are on the right track when you change it to (id : string). Now you tell JS that you only want to call your function with string. At this point the MongoDB native driver API is not in play yet. This MongoDB API is really
If you want to indicate that you can pass anything as the type for your id simple do
export const deleteDocumentWithId = (id) => {
That is, remove the type specification.
By the way you are also doing something very very wrong in your deleteDocumentWithId. You call MongoClient.connect(). You do not want to connect every time you delete.
As you can see from my first reply, I had a typo in the original question and couldn’t seem to find the “edit” button (if there is any). id should in fact be a string. However, when I call deleteOne({_id: "EXISTING_ID"}...) the MongoDB-driver requires _id to be of type ObjectId rather than type string, which is why this topic even exists.
Please prove me wrong! I’m already searching for a solution since yesterday
As to when to actually connect and disconnect: My impression was, that every connect should have a matching disconnect. My actual use-case is for end-to-end testing. The function I showed you will be eased after each test execution. Connecting and disconnecting surely lowers performance, however I don’t see a good way to implement this just yet.
It is your data that mandates which value you pass to deleteOne. If your _id is a string you must pass a string, if your _id is a number you must pass a number and if it is an ObjectId you must pass an ObjectId.
I will try to illustrate that with an example:
// Starting with the collection
c.find()
[
{ _id: 1 },
{ _id: '1' },
{ _id: ObjectId("61b9fca97bbec1567eb0bb9c") },
{ _id: ISODate("2021-12-15T14:34:57.380Z") },
{ _id: { a: 1, b: 2 } },
{ _id: { b: 2, a: 1 } },
{ _id: 1.1 }
]
// _id has many different data types. Of particular interest, it is where _id is an object both a and b fields
// of the _id object have the same values yet the _id is different, because the order of the fields are different
// The following will find { _id:1 } but not { _id:"1" } because the types are different
c.find( { _id : 1 } )
// For _id: ObjectId("61b9fca97bbec1567eb0bb9c") you must pass an ObjectId because the
// string 61b9fca97bbec1567eb0bb9c will not work because the types are different.
c.find( { _id : ObjectId("61b9fca97bbec1567eb0bb9c") } )
[ { _id: ObjectId("61b9fca97bbec1567eb0bb9c") } ]
// but with the string it finds nothing. (I used count() because it is hard to show the lack of output)
c.find( { _id : "61b9fca97bbec1567eb0bb9c" } ).count()
0
// As for the object one, only the one with the matching order and values is found
c.find( { _id: { a: 1, b: 2 } } )
[ { _id: { a: 1, b: 2 } } ]
I used find() rather than findOne() or deleteOne() because I did not want to remove my data and wanted to show that the type is important.
True. It is usually done outside the main loop of your application.
I got this answer off of my own related questions on Reddit and Stackoverflow. I didn’t find any documentation saying, that collection is generic though. This might be an issue for more users.