[GODRIVER-2659] bson.UnmarshalExtJSONWithContext does not work for $date Created: 18/Nov/22  Updated: 27/Oct/23  Resolved: 30/Nov/22

Status: Closed
Project: Go Driver
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Robin Tang Assignee: Kevin Albertson
Resolution: Works as Designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Summary

As per title. I'm unable to unmarshal a BSON document.

Please provide the version of the driver. If applicable, please provide the MongoDB server version and topology (standalone, replica set, or sharded cluster).

How to Reproduce

func (p *MongoTestSuite) TestBsonTypes() {
   var tsMap map[string]interface{}
   dc := bsoncodec.DecodeContext{Registry: bson.DefaultRegistry}
   err := bson.UnmarshalExtJSONWithContext(dc, []byte(`
{"_id": {"$numberLong": "10004"},"order_date": {"$date": 1456012800000},"purchaser_id": {"$numberLong": "1003"},"quantity": 1,"product_id": {"$numberLong": "107"}}
 
`), true, &tsMap)
   assert.NoError(p.T(), err)
   fmt.Println("tsMap", tsMap, "err", err)
   assert.True(p.T(), false)
}

 
This test will fail, and value of tsMap and the error that is returned is:

tsMap map[_id:10004] 
 
err error decoding key order_date: invalid JSON input; expected {

 

Additional Background

It's clearly able to unmarshal and fetch $numberLong, but $date is not working.



 Comments   
Comment by Kevin Albertson [ 30/Nov/22 ]

Hello rtang.cs@gmail.com, thank you for reaching out.

If so, does this SDK support v1?

No, not fully. Supporting the legacy format for $date was added in GODRIVER-742.

The existing Go library does not return `date` back in `time.Time` format, instead...it's giving it back in `ms` as well.

Unmarshalling is expected to return a primitive.DateTime. primitive.DateTime has a Time() helper. Here is an example:

{
    var tsMap map[string]interface{}
    err := UnmarshalExtJSON(
        []byte(`{"order_date": {"$date": 1456012800000}}`),
        false, /* canonical */
        &tsMap)
    assert.Nil(t, err, "got error in UnmarshalExtJSON: %v", err)
 
    val, ok := tsMap["order_date"]
    assert.True(t, ok, "did not find map key: order_date")
    dval, ok := val.(primitive.DateTime)
    assert.True(t, ok, "expected primitive.DateTime, got: %T", val)
    fmt.Printf("Time: %v\n", dval.Time())
}

Closing since this does not suggest a bug in the driver. The Jira project is for reporting bugs and feature requests. For other types of help, please post in the community forum here.

Comment by Robin Tang [ 18/Nov/22 ]

Eventually, I was able to get this solved by setting `canonical` to be `False` and using `UnmarshalExtJson(..)`

 

However, I stumbled upon this:

 

Mongoexport 2.4 and the Java driver always transform a Datetime object into an Extended JSON string of the form {"$date": <ms since epoch>}. This form has the problem of a potential loss of precision or range on the Datetimes that can be represented. Mongoexport 2.6 transforms Datetime objects into an extended JSON string of the form {"$date": <ISO-8601 date string in local time>} for dates starting at or after the Unix epoch (UTC). Dates prior to the epoch take the form {"$date": {"$numberLong": "<ms since epoch>"}}. Starting in version 3.0, mongoexport always turns Datetime objects into strings of the form {"$date": <ISO-8601 date string in UTC>}. The NPM mongodb-extended-json module does the same. The Python driver can also transform Datetime objects into strings like {"$date": {"$numberLong": "<ms since epoch>"}}. This specification canonicalises this form, since this form is the most portable.

 

The existing Go library does not return `date` back in `time.Time` format, instead...it's giving it back in `ms` as well.

 

Comment by Robin Tang [ 18/Nov/22 ]

It might be because I am using extended JSON v1, see: https://www.mongodb.com/docs/manual/reference/mongodb-extended-json-v1/#date

 

If so, does this SDK support v1?

Generated at Thu Feb 08 08:39:06 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.