Как проанализировать расширенную дату JSON в конвейере агрегации, используя ParseExtJSONArray() в mongo-go-driver
У меня есть коллекция с полем Дата:
{
"_id" : ObjectId("5b92b359ddceef5b24502834"),
"dateTimeGMT" : ISODate("2018-08-22T09:29:25.000Z"),
yada, yada, yada
}
Я пытаюсь найти по дате на этапе агрегации $match с помощью функции ParseExtJSONArray mongo-go-driver. (Я знаю, как сделать это с *bson.Array напрямую. Я спрашиваю, чтобы я знал, как правильно сделать это с ParserExtJSONArray или если я столкнулся с ограничением.)
Я упростил этот пример и подтвердил, что он не соответствует приведенному выше документу.
pipeline, err := bson.ParseExtJSONArray(`[
{ "$match": { "dateTimeGMT.$date":"2018-08-22T09:29:25.000Z" } }
]`)
cursor, err := receivedFromResponseQueue.Aggregate(ctx, pipeline)
Следующее не работает в оболочке Монго. (Не удивительно, потому что он автоматически конвертируется в формат ISODate())
db.getCollection('received_from_response_queue').aggregate([
{ "$match": { "dateTimeGMT.$date":"2018-08-22T09:29:25.000Z" } }
])
Но это работает в оболочке Монго.
db.getCollection('received_from_response_queue').aggregate([
{ "$match": { "dateTimeGMT": ISODate("2018-08-22T09:29:25.000Z") } }
])
Но это возвращает пустой массив в "конвейере". (Потому что ParseExtJSONArray не обрабатывает JavaScript)
pipeline, err := bson.ParseExtJSONArray(`[
{ "$match": { "dateTimeGMT":ISODate("2018-08-22T09:29:25.000Z") } }
]`)
Поскольку затем он использует пустой массив, он перенастраивает все документы в коллекции. Интересно, что в документе, который мы пытаемся сопоставить, дата форматируется по-разному.
{
"_id" : { "$oid" : "5b92b359ddceef5b24502834" },
"dateTimeGMT" : { "$date" : "2018-08-22T05:29:25-04:00" },
yada yada yada
}
Но это тоже не совпадает.
pipeline, err := bson.ParseExtJSONArray(`[
{ "$match": { "dateTimeGMT.$date":"2018-08-22T05:29:25-04:00" } }
]`)
cursor, err := receivedFromResponseQueue.Aggregate(ctx, pipeline)
И это не работает в оболочке Монго.
db.getCollection('received_from_response_queue').aggregate([
{ "$match": { "dateTimeGMT.$date":"2018-08-22T05:29:25-04:00" } }
])
Любое понимание?
1 ответ
Идея MongoDB Extended JSON заключается в том, чтобы представлять двоичные типы JSON ( BSON) в виде простого JSON.
Общий синтаксис должен представлять объект как один встроенный документ. Например, двоичный объект BSON представлен в виде документа {"$binary": "<binary data>"}
, $
префикс в поле ключа указывает тип. То же самое относится к объекту даты BSON.
Метод bson.ParseExtJSONArray() ожидает, что расширенные типы JSON будут документами, а не выражением нотации MongoDB. Например, вместо ниже:
{ "$match": { "dateTimeGMT.$date":"2018-08-22T09:29:25.000Z" } }
Метод ожидает:
{ "$match": { "dateTimeGMT": {"$date":"2018-08-22T09:29:25.000Z" } } }
Вы также можете указать значение даты в Unix Epoch, например:
{ "$match": { "dateTimeGMT": {"$date": { "$numberLong": "1546300800"} } } }
Используя mongo-go-driver / bson, пример будет:
raw := `[ { "$match": {"dateTimeGMT": {"$date": {"$numberLong": "1530962624753" } } } } ]`
pipeline, err := bson.ParseExtJSONArray(raw)
cursor, err := collection.Aggregate(context.Background(), pipeline)
Дополнительное примечание: вы можете отлаживать ParseExtJSONArray()
перед передачей полученного значения в агрегацию путем итерации по нему. Например:
toConvert := `[
{ "$lookup": {
"from": "anotherCollection",
"localField": "foreignKey",
"foreignField": "_id",
"as": "someField"
}},
{ "$match": {"dateTimeGMT":{"$lt": {"$date": "2019-01-10T09:29:25.000Z" } } } }
]`
pipeline, err := bson.ParseExtJSONArray(toConvert)
it, err := bson.NewArrayIterator(pipeline)
for it.Next() {
fmt.Println(it.Value().MutableDocument().ToExtJSON(true))
}
//Outputs :
// {"$lookup":{"from":"anotherCollection","localField":"foreignKey","foreignField":"_id","as":"someField"}}
// {"$match":{"dateTimeGMT":{"$lt":{"$date":{"$numberLong":"1547112565000"}}}}}
//