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

3

我尝试使用以下方法创建索引:

db.collection_name.createIndex({"field_name":1})

当我调用getIndexes()时,它会给我以下结果。
{
    "v" : 2,
    "key" : {
        "field_name" : 1.0
    },
    "name" : "field_name_1",
    "ns" : "dbname.collection_name"
}

我想知道为什么现在浮点数"field_name" : 1.0?这是不好的吗?我需要担心吗?有没有办法让它变成精确的1

另外,出于好奇,我发现我甚至可以成功地这样调用它:

db.collection_name.createIndex({"another_field_name":12345})

没有出现任何错误,我想知道在这种情况下发生了什么。

1个回答

6
您的问题实际上有几个问题,但第一个问题有一个简短的答案。
问:“为什么我会得到浮点数?”
答:因为您正在使用robomongo,该接口只是以这种方式显示提供的“Number”类型。mongo shell实际上以不同的方式显示它。
第二个问题:
问:“为什么我可以使用12345作为值而不仅仅是1或-1?”
答:因为它仍然是有效的数字。MongoDB在这里关心的只是“正数”或“负数”。因此,“正数”发出使用索引的查询将默认按“升序”排序。但是,您仍需要向特定的“.sort()”提供1或-1,因为那是唯一有效的。
为了演示后一种情况,请将一些数据插入到您的集合中:
db.collection_name.insertMany(
  [5,1,3].map( v => ({ another_field_name: v }) )  
)

并创建您的索引:

db.collection_name.createIndex({ "another_field_name": 12345 })

如果您发出一个范围查询,"升序"顺序将使用"正数"值:
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 }

这显示了索引被应用的顺序,即使实际插入值的顺序不同。因此,在这里清楚地应用了索引。

如果您尝试在此类索引上明确使用除1-1之外的任何其他值进行.sort(),那么将会产生错误。但是,当然 MongoDB 会愉快地反转索引遍历的顺序,结果分别为“升序”或“降序”。

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

db.collection_name.dropIndexes();
db.collection_name.createIndex({ "another_field_name": -54321 });

然后发出相同的查询:

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 }

然后应用“降序”排序,因为这基本上是您在默认处理中告诉它要做的。
总体来说这是好还是坏?从存储角度来看,实际呈现的值不重要,因为无论如何,BSON Double仍然是BSON Double。
您可以选择使用NumberInt来表示特定的32位值,而不是在BSON类型中指定的64位值,但是再次强调,值为165,000或相反的-1-65,000并不会改变分配的存储或其“正数”或“负数”的基本处理。
为了一般的可读性和与.sort()参数的一致性,那么“作为观点”,使用1-1更容易理解其预期目的。

实际上,这是规范中“首选”的实现方式,并且在文档中有所提及(虽然不是很突出):

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


关于:Q:“为什么我得到了一个浮点数?”A:因为您正在使用Robomongo,而界面只是以这种方式显示提供的Number类型。Mongo shell实际上会以不同的方式显示它。我不太确定,因为通过mongoDriver输入的索引在robo中显示为1,而通过robo输入的索引则表示为1.0。所以我猜测这是由于robo执行createIndex的方式造成的。 - Tomer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接