MongoDB Shell NumberInt 类型等于
MongoDB Shell NumberInt type equal
假设我们在 Mongo-Shell 中有两个 NumberInt
类型的对象:
x = NumberInt(100)
y = NumberInt(100)
当我运行下面比较的时候,我想知道为什么最后一个比较是false
?
x == 100 // True
y == 100 // True
x == y // False! Why?
不过,我确实希望通过 运行 以下行获得 false
:
x === y // False
x === 100 // False
x === 100 // False
符合预期 false
。有什么想法吗?
主要原因是相等运算符适用于原始值,但不适用于对象,函数 NumberInt() 正在 mongoshell 中定义对象:
mongos> x=100
100
mongos> typeof x
number
mongos> y=NumberInt(100)
NumberInt(100)
mongos> typeof y
object
比较对象中的值的一个选项是通过 mongoshell 中的 JSON.stringify() 将值展平为字符串,然后进行比较:
mongos> JSON.stringify(x)===JSON.stringify(y)
true
mongos>
请注意,当您将 NumberInt(100) 对象插入 mongoDB 时,它会被转换为整数,如果您读回它,则它不是对象而是数字类型:
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>
这意味着如果您从 mongoDB 中读取值,您可以毫无问题地与相等运算符进行比较...
我还没有找到确切的答案,但我想下面的大部分答案都是关于这个问题的。要理解,我们可以查看您使用的 ObjectId
实现和比较运算符。
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
这种行为的原因是在 equals
实现中,您可以看到是否只写一个没有 ()
的方法名称:
MongoDB Enterprise replset:PRIMARY> o1.equals
function(other) {
return this.str == other.str;
}
请注意,实际比较发生的不是 this
(即 ObjectId),而是内部的某个字段:
MongoDB Enterprise replset:PRIMARY> o1.str == o2.str
true
我认为 NumberInt 也会发生类似的情况,只是我还没有找到它。
注意 2,它不会影响正常工作的查询功能:
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 }
假设我们在 Mongo-Shell 中有两个 NumberInt
类型的对象:
x = NumberInt(100)
y = NumberInt(100)
当我运行下面比较的时候,我想知道为什么最后一个比较是false
?
x == 100 // True
y == 100 // True
x == y // False! Why?
不过,我确实希望通过 运行 以下行获得 false
:
x === y // False
x === 100 // False
x === 100 // False
符合预期 false
。有什么想法吗?
主要原因是相等运算符适用于原始值,但不适用于对象,函数 NumberInt() 正在 mongoshell 中定义对象:
mongos> x=100
100
mongos> typeof x
number
mongos> y=NumberInt(100)
NumberInt(100)
mongos> typeof y
object
比较对象中的值的一个选项是通过 mongoshell 中的 JSON.stringify() 将值展平为字符串,然后进行比较:
mongos> JSON.stringify(x)===JSON.stringify(y)
true
mongos>
请注意,当您将 NumberInt(100) 对象插入 mongoDB 时,它会被转换为整数,如果您读回它,则它不是对象而是数字类型:
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>
这意味着如果您从 mongoDB 中读取值,您可以毫无问题地与相等运算符进行比较...
我还没有找到确切的答案,但我想下面的大部分答案都是关于这个问题的。要理解,我们可以查看您使用的 ObjectId
实现和比较运算符。
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
这种行为的原因是在 equals
实现中,您可以看到是否只写一个没有 ()
的方法名称:
MongoDB Enterprise replset:PRIMARY> o1.equals
function(other) {
return this.str == other.str;
}
请注意,实际比较发生的不是 this
(即 ObjectId),而是内部的某个字段:
MongoDB Enterprise replset:PRIMARY> o1.str == o2.str
true
我认为 NumberInt 也会发生类似的情况,只是我还没有找到它。
注意 2,它不会影响正常工作的查询功能:
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 }