我正在尝试编写一个自动化测试,以确保我的集合中的某些字段在文档中具有一致的类型。对于这些字段中的每一个,我都有一个预期的类型。所以我要查询具有不同类型字段的文档,忽略该字段缺失的文档或null。
当字段上存在索引时,似乎不区分数字类型1(double),16(32位int)和18(64位int)。我正在使用mongo 2.6.1。这是一个演示问题的会话:
将文档插入新集合中,它有一个字段x,它是一个32位的int:
> db.typetest.insert({x:NumberInt(1)})
WriteResult({ "nInserted" : 1 })
> db.typetest.find()
{ "_id" : ObjectId("53d52620eb3748b3f9cde293"), "x" : 1 }
请注意,$ type仅匹配类型16(32位int),如预期的那样:
> db.typetest.find({x:{$type:1}})
> db.typetest.find({x:{$type:16}})
{ "_id" : ObjectId("53d52620eb3748b3f9cde293"), "x" : 1 }
> db.typetest.find({x:{$type:17}})
> db.typetest.find({x:{$type:18}})
我需要搜索与给定类型不匹配的文档,并且$不能按预期工作:
> db.typetest.find({x:{$not:{$type:1}}})
{ "_id" : ObjectId("53d52620eb3748b3f9cde293"), "x" : 1 }
> db.typetest.find({x:{$not:{$type:2}}})
{ "_id" : ObjectId("53d52620eb3748b3f9cde293"), "x" : 1 }
> db.typetest.find({x:{$not:{$type:16}}})
> db.typetest.find({x:{$not:{$type:18}}})
{ "_id" : ObjectId("53d52620eb3748b3f9cde293"), "x" : 1 }
创建索引后,$ type有效,但$ not $ type不区分3种数字类型:
> db.typetest.ensureIndex({x:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
>
> db.typetest.find({x:{$type:1}})
> db.typetest.find({x:{$type:16}})
{ "_id" : ObjectId("53d52620eb3748b3f9cde293"), "x" : 1 }
> db.typetest.find({x:{$type:17}})
> db.typetest.find({x:{$type:18}})
>
> db.typetest.find({x:{$not:{$type:1}}})
> db.typetest.find({x:{$not:{$type:16}}})
> db.typetest.find({x:{$not:{$type:18}}})
> db.typetest.find({x:{$not:{$type:2}}})
{ "_id" : ObjectId("53d52620eb3748b3f9cde293"), "x" : 1 }
如果这是mongo的预期行为,那将是一件好事。如果这是mongo的错误或限制,我会对另一种执行此测试的方式感兴趣。如果可能的话,我想避免使用$ where(出于性能原因),因为这些测试将在我们的生产数据库中经常运行。
答案 0 :(得分:1)
我测试了对MongoDB 2.6.1,2.6.3和2.4.10的否定$type
查询。
看起来MongoDB 2.4.10会返回预期的结果,但2.6查询规划器中存在一个错误。
暗示使用不包含该字段的索引来否定$type
按预期工作:
MongoDB 2.6.3> db.typetest.find({x:{$not:{$type:18}}}).hint({_id:1})
{ "_id" : ObjectId("53d600acbcad4e0896f33c90"), "x" : 1 }
Fetched 1 record(s) in 1ms
MongoDB 2.6.3> db.typetest.find({x:{$not:{$type:18}}}).hint({$natural:1})
{ "_id" : ObjectId("53d600acbcad4e0896f33c90"), "x" : 1 }
Fetched 1 record(s) in 1ms
MongoDB 2.6.3> db.typetest.find({x:{$not:{$type:18}}}).hint({x:1})
Fetched 0 record(s) in 1ms
我已将您的示例添加到错误报告SERVER-14706中,您可以观看/上传。