Compare ObjectId with string

How I can compare ObjectId with string value inside my atlas function that is called from a Trigger?

const restaurant = await restaurants.findOne({ _id: restaurantID}).then(res => {
    console.log(res);
  })

“_id” is an ObjectId
“restaurantID” is a String

Also, what is the best way to get get a value from DB?

If restaurandId is a string like "6380b9bd3b0718df59e5b71d" you simply have to call the ObjectId constructor like

const restaurant_id_as_string = "6380b9bd3b0718df59e5b71d" ;
const restaurant_id_as_oid = ObjectId( restaurant_id_as_string ) ;
const restaurant = await restaurants.findOne( { _id : restaurant_id_as_oid } ).then(res => {
    console.log(res);
  })

I have tried this and got this error:

Sorry, I missed the part that you are not running this in the mongosh or nodejs.

Try with $convert:

const restaurant = await restaurants.findOne( { _id : { "$convert" : { "input" : restaurantId , "to" : "objectId" } } ).then(res => {
    console.log(res);
  })
1 Like

you can also use $oid if restaurantID is a legit ObjectId

restaurants.findOne({ "_id": { "$oid": restaurantID } })

It does not work inside function. Do I need to add some dependency?

Does not work with “$oid” either

did you use them in quotes?
we use them all the time in queries outside Realm, so logically they should work there too.

It seems Realm functions fail to process queries as we know them. Even official docs are vague about it. For that, it is unfortunate I do not have an immediate answer for now.

I will make a new post and ask about why Realm functions fail like this. this might even be a bug in recent versions (or maybe in all).

I split myself again, one problem in one hand and a solution in the other.

I keep the problem to myself in the other post here (keep watching if interested): Why do Realm functions fail to process well-known operators (error: unknown operator)? especially for “$oid”

And here is how your problem should solve (at least worked for me):

  const bid = new BSON.ObjectId( restaurantID )
  const result = await col.find({ "_id": bid })
1 Like

I worked! Thank you :slight_smile:

1 Like

I have a side question related to that.

Why do you need to convert restaurantId to an OID?

If that value comes from a field of another to document, then this value should be stored as an object id. You do not want to keep the string representation of an object id in your database. You want to keep it as an object id.

An object id takes less space than its string representation.

It is faster to compare 2 object ids compared to comparing the string representation of the same object ids. (That last sentence sounds weird to me too.)

And the last and most important reason is you do not have to convert the string representation to an object id when you do things like you are doing. Or when you do $lookup. If you keep restaurantId as a string, you will not be able to use the simple form of $lookup with localField:restaurantId and foreignField:_id. You would have to use a pipeline that $match and $convert-ed version of each.

I can’t speak about how @Ciprian_Gabor is using it, but I can tell this has an important use case: IoT. it is where a full-fledged driver will not usually fit. device IDs will be sent over as strings.

In the App Services, you can create “HTTPS Endpoints” through which you can query the database and send back results. It is just like any CRUD API you would know: data flows mostly as strings over requests.

for example, you can directly access this endpoint with any value but will get a string as the type of arg1 (I used the sample endpoint function).
example endpoint

PS: by the way, thanks for that question. I was procrastinating to practice this endpoints and functions thing, and that help trick my lazy part :slight_smile:

What you wrote does not contradict what you I wrote.

I wrote about keeping reference to other documents inside the database as the native object id. You wrote about external interface with the data.

Yes outside the data layer, most is string. It is not a reason to bloat and slow down your data as a convenience for external entities. The same can be said with dates. You should keep dates as date object rather than the string representation for some of the same reason, take less space and faster to compare. And for dates, natural ordering and rich library. The case in point is the thread I was supposed to filter documents based on month and year between query but I'm not getting 1 month of next year due to the condition i have used any other ways to filter out where the $gte and $lte did not work as expected because dates were strings with the year last. There was also another thread were dates stored as strings needed to $convert for each document in order to be able to compute the date of the week before.

So store your data in the appropriate format and when you deal with human then you have no choice but to display or enter the values as string.

1 Like