Как найти и сравнить даты на официальном драйвере MongoDB Go?

Я новичок в mongodb-go-driver, и я застрял.

У меня есть дата внутри структуры, как:

type Email struct {
    Date        string            `json:"date"`
}

Даты на моем mongoDB и в моей структуре имеют значения типа "10/10/2018 11:55:20".

Я хочу найти в моей БД элементы, которые датируются после другой даты, я пытаюсь это сделать, но ответ всегда нулевой.

initDate, _ := time.Parse("02012006", initialDate)
cursor, err := emails.Find(context.Background(), bson.NewDocument(bson.EC.SubDocumentFromElements("date", bson.EC.DateTime("$gt", initDate.Unix()))))

Что я делаю неправильно?

2 ответа

Даты на моем mongoDB и в моей структуре имеют значения типа "10/10/2018 11:55:20".

Есть несколько способов сделать это. Первое, как упомянуто в комментарии, это преобразовать string дата в фактический формат даты. Смотрите также MongoDB Date. Хранение значений даты в правильном формате даты является рекомендуемым способом для производительности.

Если у вас есть документ:

{ "a": 1, "b": ISODate("2018-10-02T11:55:20Z") }

Используя mongo-go-driver (текущий v0.0.15), вы можете сделать следующее, чтобы найти и сравнить, используя дату:

initDate, err := time.Parse("02/01/2006 15:04:05", "01/10/2018 11:55:20")
filter := bson.VC.DocumentFromElements(
    bson.EC.SubDocumentFromElements(
        "b",
        bson.EC.Time("$gt", initDate),
    ),
)
cursor, err := collection.Find(context.Background(), filter)

Обратите внимание на значение макета в примере выше для time.Parse(), Это должно соответствовать расположению строки / формату.

Альтернативный способ без преобразования значения состоит в использовании MongoDB Aggregation Pipeline. Вы можете использовать оператор $dateFromString для преобразования string дату в дату, затем используйте $ match stage для фильтрации по дате.

Например, предоставленные документы:

{ "a": 1, "b": "02/10/2018 11:55:20" }
{ "a": 2, "b": "04/10/2018 10:37:19" }

Ты можешь попробовать:

// Add a new field called 'newdate' to store the converted date value
addFields := bson.VC.DocumentFromElements(
    bson.EC.SubDocumentFromElements(
        "$addFields",
        bson.EC.SubDocumentFromElements(
            "newdate",
            bson.EC.SubDocumentFromElements(
                "$dateFromString",
                bson.EC.String("dateString", "$b"),
                bson.EC.String("format", "%d/%m/%Y %H:%M:%S"),
            ),
        ),
    ),
)

initDate, err := time.Parse("02/01/2006 15:04:05", "02/10/2018 11:55:20")

// Filter the newly added field with the date
match := bson.VC.DocumentFromElements(
    bson.EC.SubDocumentFromElements(
        "$match",
        bson.EC.SubDocumentFromElements(
            "newdate",
            bson.EC.Time("$gt", initDate),
        ),
    ),
)
pipeline := bson.NewArray(addFields, match)

cursor, err := collection.Aggregate(context.Background(), pipeline)

Нестабильный bsonxупаковать в mongodb-go-driverимеет DateTimeТип. Вы можете добавить поле в свою структуру следующим образом:

      type Email struct {
    Date bsonx.Val
}

Чтобы объявить использование структуры bsonx.DateTime(millis int64):

      Email{
    Date: bsonx.DateTime(time.Now().UnixNano()/1e6)
}

* time.Now().UnixNano()/1e6в основном получает UNIX Millis.

И вы можете преобразовать его в time.Timeс email.Date.Time()

Другие вопросы по тегам