Uploaded image for project: 'Java Driver'
  1. Java Driver
  2. JAVA-3683

New ObjectId helper with Date and other 8 bytes zeroed

    • Type: Icon: New Feature New Feature
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 4.1.0
    • Affects Version/s: None
    • Component/s: BSON
    • Labels:
      None

      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).

            Assignee:
            jeff.yemin@mongodb.com Jeffrey Yemin
            Reporter:
            john.morales@mongodb.com John Morales (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: