Home > Mobile >  MongoDB Shell NumberInt type equal
MongoDB Shell NumberInt type equal

Time:05-29

Let say we have two objects of type NumberInt in Mongo-Shell:

x = NumberInt(100)
y = NumberInt(100)

when I run the following comparisons, I am wondering why the last comparison is false?

x == 100 // True
y == 100 // True
x == y   // False! Why?

I did however expect to get false by running the following lines:

x === y   // False
x === 100 // False
x === 100 // False

which are false as expected. Any idea?

CodePudding user response:

The main reason is that equality operators work for primitive values , but not for objects and the function NumberInt() is defining object in the mongoshell:

 mongos> x=100
 100
 mongos> typeof x
 number

 mongos> y=NumberInt(100)
 NumberInt(100)
 mongos> typeof y
 object 

One option to compare the values in objects is to flatten the values to string via the JSON.stringify() in the mongoshell and then compare:

 mongos> JSON.stringify(x)===JSON.stringify(y)
 true
 mongos> 

Note that when you insert the NumberInt(100) object to mongoDB it is converted to integer and if you read it back it is not an object but a number type:

 mongos> db.test.insert({a:y})
 WriteResult({ "nInserted" : 1 })
 mongos> db.test.find()
 { "_id" : ObjectId("6292a16069154745fd5f93c3"), "a" : 100 }
 mongos> db.test.aggregate([  {$project:{aType:{"$type":"$a"  }}} ])
 { "_id" : ObjectId("6292a16069154745fd5f93c3"), "aType" : "int" }
 mongos> var z = db.test.findOne({})
 mongos> typeof z.a
 number
 mongos>

Which mean that if you read the value from mongoDB you can compare with the equality operator without an issue ...

CodePudding user response:

I haven't found exact answer, but I guess the below mostly answers on this question. To understand we can look at ObjectId implementation and comparison operators you used.

MongoDB Enterprise replset:PRIMARY> o1 = ObjectId("507f1f77bcf86cd799439011")
ObjectId("507f1f77bcf86cd799439011")
MongoDB Enterprise replset:PRIMARY> o2 = ObjectId("507f1f77bcf86cd799439011")
ObjectId("507f1f77bcf86cd799439011")
MongoDB Enterprise replset:PRIMARY> o1.equals(o2)
true
MongoDB Enterprise replset:PRIMARY> o1 == o2  # your case 1
false
MongoDB Enterprise replset:PRIMARY> o1 === o2 # your case 2
false

The reason of this behavior is in equals implementation that you can see if you simply write a method name without ():

MongoDB Enterprise replset:PRIMARY> o1.equals
function(other) {
   return this.str == other.str;
}

notice that actual comparing happens not with this (which is ObjectId) but with some field inside:

MongoDB Enterprise replset:PRIMARY> o1.str == o2.str
true

I think something similar happens with NumberInt as well, I just didn't find it yet.

Notice2, that it doesn't affect querying functionality that just simply works:

MongoDB Enterprise replset:PRIMARY> db.coll.insertOne({a : NumberInt(100), b : NumberInt(100)})
{
        "acknowledged" : true,
        "insertedId" : ObjectId("62928aae53867e1d4ea6cee4")
}
MongoDB Enterprise replset:PRIMARY> db.coll.find({ $expr: {$eq: ["$a", "$b"]}})
{ "_id" : ObjectId("62928aae53867e1d4ea6cee4"), "a" : 100, "b" : 100 }
  • Related