Как мне извлечь созданную дату из Mongo ObjectID

Я использую оболочку Mongo для запроса моей базы данных Mongo. Я хочу использовать метку времени, содержащуюся в ObjectID, как часть моего запроса, а также как столбец для извлечения в вывод. Я настроил Mongo для самостоятельного создания ObjectID.

Моя проблема в том, что я не могу понять, как работать с ObjectID, чтобы извлечь его временную метку.

Вот вопросы, с которыми я пытаюсь работать. Поле createdDate является заполнителем; не уверен, что это за поле:

//Find everything created since 1/1/2011
db.myCollection.find({date: {$gt: new Date(2011,1,1)}});

//Find everything and return their createdDates
db.myCollection.find({},{createdDate:1});

person emilebaizel    schedule 06.09.2011    source источник


Ответы (4)


getTimestamp ()

Вам нужна эта функция, она уже включена в оболочку:

ObjectId.prototype.getTimestamp = function() {
    return new Date(parseInt(this.toString().slice(0,8), 16)*1000);
}

использованная литература

Ознакомьтесь с этим разделом в документации:

Этот модульный тест также демонстрирует то же самое:

Пример использования оболочки Mongo:

> db.col.insert( { name: "Foo" } );
> var doc = db.col.findOne( { name: "Foo" } );
> var timestamp = doc._id.getTimestamp();

> print(timestamp);
Wed Sep 07 2011 18:37:37 GMT+1000 (AUS Eastern Standard Time)

> printjson(timestamp);
ISODate("2011-09-07T08:37:37Z")
person Chris Fulstow    schedule 07.09.2011
comment
У вас есть пример вызова этой функции из оболочки? Я пробовал что-то вроде _id.getTimestamp (), но Монго это не нравится. Спасибо. - person emilebaizel; 07.09.2011
comment
Это полезно после того, как я получил данные, но я все еще не понимаю, как использовать дату создания в качестве параметра запроса. Например. «дайте мне все виджеты, которые были созданы после 01.01.2011». Может я чего то упускаю? - person emilebaizel; 07.09.2011
comment
К вашему сведению, вы также можете сделать это в одной строке: ›ObjectId (). GetTimestamp () ISODate (2011-09-07T16: 17: 10Z) - person mstearn; 07.09.2011
comment
Оказывается, вы не можете запросить дату в ObjectId. Итак, я собираюсь добавить свой столбец временных меток. Было бы неплохо использовать встроенную метку времени в ObjectId. Спасибо за помощь, связанную с запросами в наборах результатов! - person emilebaizel; 14.09.2011
comment
Вы, вероятно, можете сделать это: db.col.find( { $where: "this._id.getTimestamp() > new Date(2011,0,1)" } ); но это будет медленным при обработке больших наборов данных, потому что он выполняет JavaScript для каждого документа. Я бы выделил отдельную колонку. - person Chris Fulstow; 14.09.2011
comment
Все это дает мне AttributeError: объект 'ObjectId' не имеет атрибута 'getTimeStamp' - person zakdances; 15.08.2012
comment
@yourfriendzak Метод называется getTimestamp () docs.mongodb. org / manual / reference / method / ObjectId.getTimestamp / - person Alex Bitek; 03.01.2013
comment
@emilebaizel Вы можете использовать временную метку в запросе, но сначала вам нужно преобразовать 10-значную временную метку UNIX в шестнадцатеричную строку из 8 символов, а затем добавить к ней 0000000000000000 (в конце строка должна иметь ровно 24 символа). Затем вы берете полученную строку и используете ее в качестве идентификатора объекта в запросах MongoDB. См. Мой комментарий здесь: пример goo.gl/XJDa1. - person Alex Bitek; 03.01.2013
comment
Я создал простую веб-страницу для извлечения метки времени из заданного Mongo ObjectId: paumoreno.net/mongoid Надеюсь может быть полезно! - person pau.moreno; 22.12.2013
comment
Если вам нужно отобразить только год или месяц и т. Д., Вы можете использовать print(timestamp.getFullYear()) или print(timestamp.getMonth() + 1) - person boryn; 01.04.2014
comment
Я бы сменил this.toString() на this.str. Из-за этого у меня не получалось. В результате функция будет выглядеть так: ObjectId.prototype.getTimestamp = function() { return new Date(parseInt(this.str.slice(0,8), 16)*1000); } - person Jose Enrique; 05.11.2016
comment
домен mongodb docs изменен с .org на .com - person Phani Rithvij; 09.03.2021

Этот вопрос помогает понять, как использовать _id встроенная метка времени в ситуациях запроса (см. документацию Mongo Extended JSON). Вот как это делается:

col.find({..., 
     '_id' : {'$lt' : {'$oid' : '50314b8e9bcf000000000000'}} 
})

находит документы, созданные раньше, чем предоставленный oid. При использовании вместе с естественной сортировкой и ограничением вы можете использовать BSON _ids для создания запросов API, подобных Twitter (дайте мне последний имеющийся у вас OID, и я предоставлю еще двадцать)

person Stefan    schedule 21.08.2012
comment
Ваш ответ действительно можно использовать в запросе mongo. Спасибо ! - person Albert Gan; 13.12.2012
comment
Это работает только с помощью команды mongoexport: mongoexport -d twitter -c tweets -q '{_id: {$ gte: {$ oid: 50e54ec00000000000000000}}' Я не могу получить никаких результатов, используя оболочка mongo: db.tweets.find ({_ id: {$ gte: {$ oid: 50e54ec00000000000000000}}}) - person Alex Bitek; 03.01.2013
comment
Удалось заставить его работать и в оболочке Mongo: db.tweets.find({ "_id" : { $gte : ObjectId("50d314e40000000000000000") } }) и с использованием драйвера C ++ MongoDB со следующим запросом: std::string qs = "{ \"_id\" : { $gte : { \"$oid\" : \"" + oid + "\" } } }"; std::auto_ptr<mongo::DBClientCursor> cursor = c.query("twitter.tweets", mongo::Query(qs)); - person Alex Bitek; 03.01.2013

В python вы можете сделать это:

>>> from bson.objectid import ObjectId
>>> gen_time = datetime.datetime(2010, 1, 1)
>>> dummy_id = ObjectId.from_datetime(gen_time)
>>> result = collection.find({"_id": {"$lt": dummy_id}})

Я думаю, ObjectId.from_datetime () - это полезный метод стандартной библиотеки bson. Возможно, у других языковых привязок есть альтернативная встроенная функция. Источник: http://api.mongodb.org/python/current/api/bson/objectid.html

person es2    schedule 09.10.2014
comment
Или, другими словами: хорошие ответы сопровождаются примерами кода с объяснениями для будущих читателей. Хотя человек, задающий этот вопрос, может понять ваш ответ, объяснение того, как вы к нему пришли, может помочь бесчисленному количеству других. - person Stonz2; 09.10.2014
comment
извините, я думаю, что пропустил тему и ответил на другой вопрос - person es2; 10.10.2014

Чтобы использовать метку времени, содержащуюся в ObjectId, и возвращать документы, созданные после определенной даты, вы можете использовать $where с функцией.

e.g.

db.yourcollection.find( { 
  $where: function() { 
    return this._id.getTimestamp() > new Date("2020-10-01")
  } 
});

Функция должна возвращать истинное значение, чтобы этот документ был включен в результаты. Ссылка: $ where

Однако объекты даты Mongo могут показаться немного странными. Подробную информацию о конструкторе см. В документации mongo Date ().

выдержка:

You can specify a particular date by passing an ISO-8601 date string with a year within the inclusive range 0 through 9999 to the new Date() constructor or the ISODate() function. These functions accept the following formats:

    new Date("<YYYY-mm-dd>") returns the ISODate with the specified date.
    new Date("<YYYY-mm-ddTHH:MM:ss>") specifies the datetime in the client’s local timezone and returns the ISODate with the specified datetime in UTC.
    new Date("<YYYY-mm-ddTHH:MM:ssZ>") specifies the datetime in UTC and returns the ISODate with the specified datetime in UTC.
    new Date(<integer>) specifies the datetime as milliseconds since the Unix epoch (Jan 1, 1970), and returns the resulting ISODate instance.

person user1160006    schedule 16.10.2020