Использование time.Time в mongodb record

Я вставляю новый элемент в коллекцию. Для этого используйте официальный драйвер mongo go ( https://github.com/mongodb/mongo-go-driver).

collection.InsertOne(context.Background(), map[string]interface{}{
    "string":   "test",
    "integer":  123,
    "float":    0.123,
    "array":    []string{"t", "e", "s", "t"},
    "objectid": objectid.New(),
    "time":     time.Now(),
})

Но в результате у меня проблема с парой свойств: time.Time и objectid.ObjectID.

  • time.Time идет как объект, который пуст
  • objectid.ObjectID - как двоичный

Я понимаю, что это только в альфа-состоянии, но, возможно, кто-то знает. Я просто делаю это неправильно или все еще не реализовано так, как должно быть?

2 ответа

Решение

Если вы передаете map в качестве документа для Collection.InsertOne(), mongo Пакет будет использовать mongo.TransformDocument() преобразовать его в *bson.Document значение, потому что большинство операций осуществляются только на bson.Document s.

Текущая реализация преобразования не обрабатывает objectid.ObjectID ни time.Time типы. Это могло и вероятно должно, и я предполагаю, что это будет, но в настоящее время это не так.

Если вы хотите, чтобы эти типы заканчивались правильными типами в MongoDB, вы можете создать и передать *bson.Document себя, в котором вы можете явно диктовать, какие типы свойств должны быть.

Это эквивалентный оператор вставки для вас, используя bson.NewDocument() создать документ вручную:

res, err := coll.InsertOne(context.Background(), bson.NewDocument(
    bson.EC.String("string", "test"),
    bson.EC.Int64("integer", 123),
    bson.EC.Double("float", 0.123),
    bson.EC.ArrayFromElements("array",
        bson.VC.String("t"), bson.VC.String("e"),
        bson.VC.String("s"), bson.VC.String("t")),
    bson.EC.ObjectID("objectid", objectid.New()),
    bson.EC.DateTime("time", time.Now().UnixNano()/1e6), // Must pass milliseconds
))

Это более многословно, но явно в том, что мы хотим, чтобы результирующий документ в MongoDB был. Итоговый документ будет выглядеть так:

{
    "_id" : ObjectId("5ac5f598ca151255c6fc0ffb"),
    "string" : "test",
    "integer" : NumberLong(123),
    "float" : 0.123,
    "array" : [
        "t",
        "e",
        "s",
        "t"
    ],
    "objectid" : ObjectId("5ac5f598ca151255c6fc0ffa"),
    "time" : ISODate("2018-04-05T10:08:24.148Z")
}

Как только драйвер улучшится, я предполагаю, что ваша оригинальная версия будет работать как положено и создаст документ, идентичный этому по структуре.

Вам нужно будет преобразовать время в строку или в Unix. time.Now() время типа, которое является структурой.

a := time.Now()
fmt.Println(a.Unix()) // Goes into mongodb as a int64
fmt.Println(a.String()) // Goes inot mongodb as a string

1522868253 // Unix

2018-04-04 13:57:33.495965 -0500 CDT m=+0.000363419 // Строка

Так что вы можете сделать это

collection.InsertOne(context.Background(), map[string]interface{}{
    "string":   "test",
    "integer":  123,
    "float":    0.123,
    "array":    []string{"t", "e", "s", "t"},
    "objectid": objectid.New(),
    "time":     time.Now().String(),
})
Другие вопросы по тегам