我有一个包含20个用户的集合,其中19个没有具有稀疏索引的属性created_at
。
当我在mongo命令行中运行以下命令时,它返回1个文档(具有created_at
属性的文档)
db.users.find().sort({created_at: 1})
如何对created_at
进行排序,还可以获取没有created_at
属性的所有对象
注意:这只是一个例子,真正的集合更大(而不是用户),我们需要字段上的稀疏索引
更新:我使用版本2.4.9(所以我需要升级它,并使用下面的解决方案) http://docs.mongodb.org/manual/core/index-sparse/#sparse-index-incomplete-results
答案 0 :(得分:2)
听起来你在" created_at"上定义了"sparse index"。字段,这是您看到此行为的唯一原因。
将以下文件作为样本:
{ "_id" : ObjectId("54082229b70a1512aacb5e7e"), "x" : 1, "y" : 1 }
{ "_id" : ObjectId("5408222fb70a1512aacb5e7f"), "x" : 2 }
{ "_id" : ObjectId("54082231b70a1512aacb5e80"), "x" : 3 }
如果你只是想"排序"在" y"在这里你应该得到这样的结果:
> db.test.find().sort({ y: 1 })
{ "_id" : ObjectId("5408222fb70a1512aacb5e7f"), "x" : 2 }
{ "_id" : ObjectId("54082231b70a1512aacb5e80"), "x" : 3 }
{ "_id" : ObjectId("54082229b70a1512aacb5e7e"), "x" : 1, "y" : 1 }
但是如果添加稀疏索引:
db.test.ensureIndex({ y: 1 },{ sparse: true })
然后结果不同,但是对于小数据我们需要强制索引:
> db.test.find().hint({ y: 1 }).sort({ y: 1 })
{ "_id" : ObjectId("54082229b70a1512aacb5e7e"), "x" : 1, "y" : 1 }
这是发生这种情况的唯一情况,默认情况下,非现场字段将被视为null
而"低于"存在的其他值。
所以如果索引改变了:
db.test.dropIndexes()
db.test.ensureIndex({ y: 1 })
并且问题相同,结果将与原始相同:
> db.test.find().hint({ y: 1 }).sort({ y: 1 })
{ "_id" : ObjectId("5408222fb70a1512aacb5e7f"), "x" : 2 }
{ "_id" : ObjectId("54082231b70a1512aacb5e80"), "x" : 3 }
{ "_id" : ObjectId("54082229b70a1512aacb5e7e"), "x" : 1, "y" : 1 }
这就是稀疏索引如何通过排除索引字段不存在的文档来影响结果。
您可以查看以下内容:
> db.test.getIndexes()
{
"v" : 1,
"key" : {
"y" : 1
},
"name" : "y_1",
"ns" : "test.test",
"sparse" : true
}
如果这是由您的ODM设置自动创建的,那么您可能需要手动查看"指定要使用的索引条件。
注意:即使修复了索引,也没有" created_at"字段仍然会以升序排列。在不修改数据的情况下,您需要像汇总框架这样的东西来投射一个值,该值将大于预期的日期值,而这个值已经不存在了。