65

I'm using mongodb native driver in a nodejs environment and I need to convert an id string to ObjectId to use it in my update query, how can I do this?

ItachiUchiha
  • 36,135
  • 10
  • 122
  • 176
Nasser Torabzade
  • 6,490
  • 8
  • 27
  • 36

4 Answers4

96

with ObjectId (nodejs driver doc)

When you have a string representing a BSON ObjectId (received from a web request for example), then you need to convert it to an ObjectId instance:

const {ObjectId} = require('mongodb'); // or ObjectID 
// or var ObjectId = require('mongodb').ObjectId if node version < 6

const updateStuff = (id, doc) => {
  // `ObjectId` can throw https://github.com/mongodb/js-bson/blob/0.5/lib/bson/objectid.js#L22-L51, it's better anyway to sanitize the string first
  if (!ObjectId.isValid(s)) {
    return Promise.reject(new TypeError(`Invalid id: ${id}`));
  }
  return collection.findOneAndUpdate(
    {_id: ObjectId(id)}, 
    {$set: doc}, 
    {returnOriginal: false}
  );
};
caub
  • 2,709
  • 2
  • 28
  • 31
  • thanks, you're right about my use case. but if I generate `_id` in client side, isn't it required to check its uniqueness in my collection? I supposed that check is more expensive than type casting in server side, what do you think? – Nasser Torabzade Jan 12 '14 at 15:52
  • 1
    "If the value were not unique, the insert would fail" from docs.mongodb.org/manual/reference/method/db.collection.insert, and I don't know about performances of each method, but ObjectIds are just 24bytes hash, it's up to your implementation – caub Feb 14 '14 at 00:49
  • Hello, @caub Thanks for your valuable answer. I am kinda newbie in Angular 2/4 and MongoDb. In my application, i am using Angular 2, LoopBack and MongoDb. I am not sure where this chunk of code should be added!! Shall it be added in Angular typescript file or in LoopBack server file? Can you guide me on this. I am completely stuck at this point of time. If i am adding this code in typescript file then i am getting below error: Module not found: Error: Can't resolve 'mongodb' – Prasad Kaiche Mar 07 '18 at 06:37
  • This logic is on the server, It's using [`mongodb`](http://npm.im/mongodb) driver package (nodejs only) – caub Mar 07 '18 at 09:41
  • @PrasadKaiche `ObjectId` alone could be [used on client or server](https://runkit.com/caub/5aaa82b8d16c2700128f6c17) but if you do, be careful on how those ids get generated to make sure they are as much unique as possible – caub Mar 15 '18 at 14:29
11
var {ObjectId} = require('mongodb'); // or ObjectID Not Working

as mentioned by @caubub won't work for me.

But when I use var ObjectID = require('mongodb').ObjectID; // convert string to ObjectID in mongodb then I am able to convert string to ObjectId in nodejs mongodb native drive.

For reference visit to http://mongodb.github.io/node-mongodb-native/2.2/api/ObjectID.html

Seb33300
  • 7,464
  • 2
  • 40
  • 57
VIKAS KOHLI
  • 8,164
  • 4
  • 50
  • 61
  • 3
    To clarify, ES6 object destructuring (`{ ObjectID } = require...`) only works on Node version 6.0 and above, older versions require the old syntax. – MacK May 17 '18 at 10:45
  • 3
    ObjectID (with capital "D") is deprecated. Use ObjectId (lowercase "d") instead. (source: `@types/bson` package) – Hendy Irawan Apr 05 '20 at 10:42
1

You can use $toObjectId in agregation pipeline something like that :

db.CollectionWithStringId.aggregate([
{$addFields: {
    _id: { $toObjectId: "$_id" }
}}

])

source :https://docs.mongodb.com/manual/reference/operator/aggregation/toObjectId/

clement box
  • 130
  • 1
  • 8
0

My mongodb version: 4.9.1 (nodejs)

You just have to:

import { Collection, ObjectId } from "mongodb";

And then for example delete a document, you just:

return await collection.deleteOne({ _id: new ObjectId(id)});