Package does not have functionality to limit flatten depth. i.e specify how deep object should be flattened.
package main
import (
"encoding/json"
"errors"
"fmt"
"log"
"time"
"github.com/chidiwilliams/flatbson"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/bsontype"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type doc struct {
ID *primitive.ObjectID `bson:"_id,omitempty"`
Data *Data `bson:"data,omitempty"`
}
type Data struct {
Name string `bson:"name,omitempty"`
Date *Date `bson:"date,omitempty"`
}
type obj = map[string]interface{}
func main() {
client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017/partedit"))
if err != nil {
log.Fatalln(err)
}
if err := client.Connect(nil); err != nil {
log.Fatalln(err)
}
db := client.Database("partedit")
col := db.Collection("partials")
initialDate, updatedDate := time.Date(2020, 5, 22, 0, 0, 0, 0, time.UTC), time.Date(2020, 4, 12, 0, 0, 0, 0, time.UTC)
doc1 := &doc{
Data: &Data{
Name: "Oghogho",
Date: &Date{initialDate},
},
}
doc2 := &doc{
Data: &Data{
Date: &Date{updatedDate},
},
}
out1, out2 := new(doc), new(doc)
id, err := col.InsertOne(nil, doc1)
if err != nil {
log.Fatalln(err)
}
res1 := col.FindOne(nil, bson.D{{Key: "_id", Value: id.InsertedID}})
if err := res1.Decode(out1); err != nil {
log.Fatalln(err)
}
r, _ := json.Marshal(out1.Data)
fmt.Printf("Inserted document: %s\n", r)
update, err := flatbson.Flatten(doc2)
if err != nil {
log.Fatalln(err)
}
res2 := col.FindOneAndUpdate(nil, bson.D{{Key: "_id", Value: id.InsertedID}}, obj{"$set": update}, options.FindOneAndUpdate().SetReturnDocument(options.After))
if err := res2.Decode(out2); err != nil {
log.Fatalln(err)
}
r, _ = json.Marshal(out2.Data)
fmt.Printf("Document after update: %s\n", r)
}
type Date struct {
time.Time
}
func NewDate(t time.Time) *Date {
return &Date{t}
}
func (d *Date) UnmarshalBSON(data []byte) error {
val := bson.RawValue{
Type: bsontype.DateTime,
Value: data,
}
stamp, ok := val.DateTimeOK()
if !ok {
return errors.New("Invalid datetime")
}
newTime := time.Unix(stamp/1000, 0)
d.Time = time.Date(newTime.Year(), newTime.Month(), newTime.Day(), 0, 0, 0, 0, time.UTC)
return nil
}
func (d *Date) MarshalBSONValue() (bsontype.Type, []byte, error) {
return bson.MarshalValue(d.Time)
}
func (d *Date) MarshalJSON() ([]byte, error) {
return json.Marshal(d.Time.Format("2006-01-02"))
}
Inserted document: {"Name":"Oghogho","Date":"2020-05-22"}
Document after update: {"Name":"Oghogho","Date":"2020-04-12"}
Inserted document: {"Name":"Oghogho","Date":"2020-05-22"}
2020/05/22 11:04:38 (PathNotViable) Cannot create field 'time' in element {date: new Date(1590141878506)}
exit status 1