MongoDB 索引异常的非 1 或 -1 值

Sim*_*leV 3 mongodb

我尝试使用创建索引

db.collection_name.createIndex({"field_name":1})
Run Code Online (Sandbox Code Playgroud)

然后当我打电话时getIndexes()它会给我以下结果

{
    "v" : 2,
    "key" : {
        "field_name" : 1.0
    },
    "name" : "field_name_1",
    "ns" : "dbname.collection_name"
}
Run Code Online (Sandbox Code Playgroud)

"field_name" : 1.0所以我想知道为什么现在是浮点数?是不是很糟糕?我还应该担心吗?有什么办法可以准确做到吗1

出于好奇:我注意到我什至可以成功地这样称呼它:

db.collection_name.createIndex({"another_field_name":12345})
Run Code Online (Sandbox Code Playgroud)

不会产生任何错误。我想知道这个案例中发生了什么。

Nei*_*unn 6

你的问题实际上是几个问题,但第一个问题有一个简短的答案

问: “为什么我会得到浮点数?”

答:因为您使用的是 robomongo,并且界面只是以Number这种方式显示提供的类型。shellmongo实际上以不同的方式显示这一点

第二个:

问: “为什么我可以使用12345as 值而不是仅使用1or -1?”

:因为它实际上仍然是数字且有效。MongoDB在这里关心的只是“积极”或“消极”。因此,如果“正”发出使用索引的查询,则默认情况下将按“升序”排序。但您仍然需要提供1or-1到特定的.sort(),因为这就是有效的。

为了演示后一种情况,请将一些数据插入到您的集合中:

db.collection_name.insertMany(
  [5,1,3].map( v => ({ another_field_name: v }) )  
)
Run Code Online (Sandbox Code Playgroud)

并创建您的索引:

db.collection_name.createIndex({ "another_field_name": 12345 })
Run Code Online (Sandbox Code Playgroud)

如果发出范围查询,则“正”值将使用“升序”顺序:

db.collection_name.find({ "another_field_name": { "$gt": 0 } },{ "_id": 0 })

{ "another_field_name" : 1.0 }
{ "another_field_name" : 3.0 }
{ "another_field_name" : 5.0 }
Run Code Online (Sandbox Code Playgroud)

这显示了应用索引的顺序,即使实际插入值的顺序不同。所以这里明确应用了索引。

如果您尝试在此类索引上显式使用.sort()任何其他值,则会产生错误。当然,这会分别导致“升序”或“降序”排序,因为 MongoDB 会很乐意反转索引的遍历顺序。1-1

如果您删除了索引并使用“负”值创建了一个索引:

db.collection_name.dropIndexes();
db.collection_name.createIndex({ "another_field_name": -54321 });
Run Code Online (Sandbox Code Playgroud)

然后发出相同的查询:

db.collection_name.find({ "another_field_name": { "$gt": 0 } },{ "_id": 0 })

{ "another_field_name" : 5.0 }
{ "another_field_name" : 3.0 }
{ "another_field_name" : 1.0 }
Run Code Online (Sandbox Code Playgroud)

然后应用“降序”顺序,因为这本质上是您告诉它在默认处理中执行的操作。

这总体上是好是坏?从存储的角度来看,这实际上并不重要,因为无论 BSON Double 呈现的实际值如何仍然是 BSON Double。

您可以交替使用NumberInt特定的 32 位值,而不是BSON Types中指定的 64 位值,但同样,该值是1or65,000或 相反,因为-1-65,000不会更改分配的存储或它所在位置的基本处理是“正”还是“负”。

为了总体可读性和与当时.sort()作为“意见问题”的论点的一致性,使用1and-1使其更一致地理解其预期目的。

它实际上是规范中的“首选”实现,并且在文档中有所呼应(尽管不是很突出):

某些驱动程序可能会使用 NumberLong(1) 而不是 1 作为规范来指定索引。这不会对结果索引产生任何影响。