Mongodb集合中并没有强制所有文档具有统一的结构和字段类型。这样宽松的文档结构管理方法,给新数据的插入和以有数据的修改带来了极大的便利。但数据类型的频繁修改,可能参数查询和处理上的问题。
数值类型的变化, 是mongodb面临的一个问题之一。 项目设计之初,数值类型可能选择默认的整型。开发过程中数据的变化, 变成了浮点型。而浮点型不能够提供高精度计算,这字段类型又变成了小数类型decimal。针对不同数字类型的查询,mongodb有不同的结果。刚好在浏览mongodb文档时,发现了这个有趣的查询方法,整理并分享出来。
在types集合中,有5条数据,字段value值是不同的数据类型。包括整型,长整型,浮点型和小数类型decimal.
db.types.insertMany([
{_id: 1, value: 1, expectedType: "Int32"},
{_id: 2, value: Long("1"), expectedType: "Long"},
{_id: 3, value: 1.01, expectedType: "Double"},
{_id: 4, value: Decimal128("1.01"), expectedType: "Decimal128"},
{_id: 5, value: 3200000001, expectedType: "Double"},
])
db.types.find({value: {$type: "int"}})
{
"_id" : 1,
"value" : 1,
"expectedType" : "Int32"
}
db.types.find({value: {$type: "long"}})
{
"_id" : 2,
"value" : Long("1"),
"expectedType" : "Long"
}
db.types.find({value: {$type: "decimal"}})
{
"_id" : 4,
"value" : Decimal128("1.01"),
"expectedType" : "Decimal128"
}
db.types.find({value: {$type: "double"}})
/* 1 */
{
"_id" : 3,
"value" : 1.01,
"expectedType" : "Double"
},
/* 2 */
{
"_id" : 5,
"value" : Double("3200000001"),
"expectedType" : "Double"
}
db.types.find({value: {$type: "number"}})
/* 1 */
{
"_id" : 1,
"value" : 1,
"expectedType" : "Int32"
},
/* 2 */
{
"_id" : 2,
"value" : Long("1"),
"expectedType" : "Long"
},
/* 3 */
{
"_id" : 3,
"value" : 1.01,
"expectedType" : "Double"
},
/* 4 */
{
"_id" : 4,
"value" : Decimal128("1.01"),
"expectedType" : "Decimal128"
},
/* 5 */
{
"_id" : 5,
"value" : Double("3200000001"),
"expectedType" : "Double"
}
db.types.find({value: 1.01})
{
"_id" : 3,
"value" : 1.01,
"expectedType" : "Double"
}
db.types.find({value: 1})
/* 1 */
{
"_id" : 1,
"value" : 1,
"expectedType" : "Int32"
},
/* 2 */
{
"_id" : 2,
"value" : Long("1"),
"expectedType" : "Long"
}
几个查询语句中,最奇怪的当属查询值为1.01的查询语句了。 插入数据时, _id为3和_id为4的数据,数值上来看,都是1.01。但两个数值的类型不同。mongodb在使用{value: 1.01}查询时,隐式的将1.01转化为Double的类型。这样decimal128类型的数据就查不到了。
这里在程序开发过程中,是极易出错的点。在文档中看到了这个有趣的案例,就所幸记录下来。