[SERVER-49540] Wrong document returned by find({_id: value as Int64}) Created: 16/Jul/20  Updated: 27/Oct/23  Resolved: 16/Jul/20

Status: Closed
Project: Core Server
Component/s: None
Affects Version/s: 4.0.4
Fix Version/s: None

Type: Bug Priority: Critical - P2
Reporter: Szaniszlo Szöke Assignee: Unassigned
Resolution: Works as Designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: JPEG File BugMongo01.jpg     JPEG File BugMongo03.jpg    
Operating System: ALL
Steps To Reproduce:

Store documents using an _id of type 64 bit integer.

Add items, and search.

Participants:

 Description   

A search like : db.getCollection('gff').find({_id:71549674884444169})

returns document with _id = 71549674884444168

There is a 1 offset in the _id value.

Happens in Mongo Compass and in Robot3T.

 



 Comments   
Comment by Bruce Lucas (Inactive) [ 16/Jul/20 ]

You're welcome, and happy your problem has been resolved.

Comment by Szaniszlo Szöke [ 16/Jul/20 ]

Thanks a lot for you super-fast answer.

Works fine with the C# drivers too.

 

Comment by Bruce Lucas (Inactive) [ 16/Jul/20 ]

szoke.szaniszlo@gmail.com, this is occurring because Javascript stores 71549674884444169 as a floating-point number, which has only 53 bits of precision, so cannot represent all 64-bit numbers. In order to query a db that has 64-bit _ids from Javascript you need to use NumberLong to construct a 64-bit number. The following illustrates this point:

Insert two records with 64-bit integer _ids

> db.c.insert({_id: NumberLong("71549674884444168")})
> db.c.insert({_id: NumberLong("71549674884444169")})

Find using 71549674884444169 returns the wrong document as you indicated because the low order bits of the number are lost when it is stored as floating point and then converted to 64-bit integer to query the db:

> db.c.find({_id: 71549674884444169})
{ "_id" : NumberLong("71549674884444168") }

But if you use NumberLong("71549674884444169") the right document is returned:

> db.c.find({_id: NumberLong("71549674884444169")})
{ "_id" : NumberLong("71549674884444169") }

Since this is working as expected I will close the ticket.

Comment by Szaniszlo Szöke [ 16/Jul/20 ]

The same applies to the latest version (4.2.8).

It seems that the value is rounded and that the server returns some value "close" to the filter value.

Generated at Thu Feb 08 05:20:11 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.