0

As part of an upgrade script, I want to use $where to find docs where the id matches one of the fields. I know that's slow because it's done with a cursor, but that's OK with me; I'm only going to run it once. But I can't get it to work:

> db.things.drop()
true

> stuff = {}
{ }

> db.things.save(stuff)

> stuff.original_id = stuff._id
ObjectId("4ff5f9f97fadec5abb7b5392")

> db.things.save(stuff)

//why doesn't this return anything?
> db.things.find({$where: "this._id == this.original_id"})

//interstingly, this works fine
> db.things.find({$where: "this._id == this._id"})
{ "_id" : ObjectId("4ff5f9f97fadec5abb7b5392"), "original_id" : ObjectId("4ff5f9f97fadec5abb7b5392") }

What's wrong here? Why can't I compare _id to original_id?

1 Answers1

1

ObjectId is an object. The == operator here tests for reference equality.

> ObjectId("4ff5fbed3a015a91f85e80bb") == ObjectId("4ff5fbed3a015a91f85e80bb")
false    

But if operands are simpler types (numbers or strings) it checks for value equality.

> '4ff5fbed3a015a91f85e80bb' == '4ff5fbed3a015a91f85e80bb'
true

So, this simple workaround will work:

> db.where.find({$where: "this._id.toString() == this.orig_id.toString()"})
{ "_id" : ObjectId("4ff5fbed3a015a91f85e80bb"), "orig_id" : ObjectId("4ff5fbed3a015a91f85e80bb") }

Here's a post with much more info on comparison operators in Javascript.

And here's another article.

Community
  • 1
  • 1
Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
  • Ah, I should have thought of that. See the rules in the === section here: http://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/ –  Jul 05 '12 at 20:52