[JAVA-3683] New ObjectId helper with Date and other 8 bytes zeroed Created: 04/Apr/20  Updated: 28/Oct/23  Resolved: 05/May/20

Status: Closed
Project: Java Driver
Component/s: BSON
Affects Version/s: None
Fix Version/s: 4.1.0

Type: New Feature Priority: Major - P3
Reporter: John Morales Assignee: Jeffrey Yemin
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The application I work on frequently creates ObjectId's with ObjectId.createFromLegacyFormat(int, int, int), always passing as arguments a non-zero timestamp, and then a zero machine and inc. This is useful as a way of performing date range queries by _id.

E.g., as shell-ish syntax pseudocode:

{_id: {$gte: ObjectId(Date("2020-04-01T00:00:00Z")), $lt: ObjectId(Date("2020-04-02T00:00:00Z"))}}

With the deprecation of the ObjectId.createFromLegacyFormat() method some public non-Deprecated constructors remain that take a Date argument. However, none of these constructors allow for zeroing the other 8 bytes of the ObjectId. Instead, the generated ObjectId's will have two random values for machine/process:
https://github.com/mongodb/mongo-java-driver/blob/3.12.x/bson/src/main/org/bson/types/ObjectId.java#L180-L182

This difference of there being no alternative constructors that allow control of the machine/process bits is there's now no helper to construct ObjectId's for my range queries such that I get a deterministic set of results.

For example, suppose a document exists in my collection that has 4-byte timestamp of exactly Date("2020-04-01T00:00:00Z").epochSeconds(), but its process/machine bits are lower than the process/machine bits of the ObjectId generated for my query. Now my query won't return this document. And suppose my query pattern like this repeats as a daily job. Then it will always be non-deterministic whether I in fact end up reading every document, or if sometimes I get "unlucky" and document(s) are missed at the boundary. By contrast, with the ObjectId.createFromLegacyFormat(Date("2020-04-01T00:00:00Z"), 0, 0) approach, I am guaranteed to deterministically return every document over these adjacent ranges.

To mention it, there is one more non-Deprecated alternative that would work, just not a convenient one. I could instead switch to using ObjectId(ByteBuffer) where I write my 12 bytes by hand. Certainly doable, but a helper or constructor would be much nicer (especially since one used to exist).



 Comments   
Comment by Githook User [ 05/May/20 ]

Author:

{'name': 'Jeff Yemin', 'email': 'jeff.yemin@10gen.com', 'username': 'jyemin'}

Message: Add getSmallestWithDate factory method to ObjectId

JAVA-3683
Branch: master
https://github.com/mongodb/mongo-java-driver/commit/a1a668fd3d44ba32ab61242ea06a8df3eb0c9e23

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