Подтвердить что ты не робот

Использует для mongodb время создания ObjectId

ObjectId, используемый в качестве ключа по умолчанию в документах mongodb, имеет встроенную метку времени (вызов objectid.generation_time возвращает объект datetime). Таким образом, можно использовать это время генерации вместо того, чтобы хранить отдельную временную метку создания? Как вы сможете сортировать по времени создания или запросу для последних элементов N эффективно используя эту встроенную метку времени?

4b9b3361

Ответ 1

Я полагаю, что поскольку MongoDB ObjectId содержит метку времени, вы можете сортировать по "созданной дате", если сортировать по объекту:

items.find.sort( [['_id', -1]] ) // get all items desc by created date.

И если вы хотите, чтобы последние 30 созданных элементов вы могли использовать следующий запрос:

items.find.sort( [['_id', -1]] ).limit(30) // get last 30 createad items 

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

Update:

Да, это так. Если вы закажете _id, вы автоматически закажете по дате, указанной в _id. Я сделал небольшой тест в С#, кто-то заинтересован в нем:

  public class Item
  {
    [BsonId]
    public ObjectId Id { get; set; }

    public DateTime CreatedDate { get; set; }

    public int Index { get; set; }
  }



 [TestMethod]
 public void IdSortingTest()
 {
   var server = MongoServer.Create("mongodb://localhost:27020");
   var database = server.GetDatabase("tesdb");

   var collection = database.GetCollection("idSortTest");
   collection.RemoveAll();

   for (int i = 0; i <= 500; i++)
   {
     collection.Insert(new Item() { 
             Id = ObjectId.GenerateNewId(), 
             CreatedDate = DateTime.Now, 
             Index = i });
   }

   var cursor = collection.FindAllAs<Item>();
   cursor.SetSortOrder(SortBy.Descending("_id"));
   var itemsOrderedById = cursor.ToList();

   var cursor2 = collection.FindAllAs<Item>();
   cursor2.SetSortOrder(SortBy.Descending("CreatedDate"));
   var itemsOrderedCreatedDate = cursor.ToList();

   for (int i = 0; i <= 500; i++)
   {
     Assert.AreEqual(itemsOrderedById[i].Index, itemsOrderedCreatedDate[i].Index);
   }
}

Ответ 2

Да, вы можете использовать время генерации BSON ObjectId для тех целей, которые вы хотите. Таким образом,

db.collection.find().sort({ _id : -1 }).limit(10)

вернет последние 10 созданных элементов. Однако, поскольку встроенные временные метки имеют точность в одну секунду, несколько элементов в течение любой секунды сохраняются в порядке их создания.

Ответ 3

Код для преобразования DateTime в соответствующую метку времени с помощью драйвера С# выглядит следующим образом:

    public static ObjectId ToObjectId(this DateTime dateTime)
    {
        var timestamp = (int)(dateTime - BsonConstants.UnixEpoch).TotalSeconds;
        return new ObjectId(timestamp, 0, 0, 0);
    }

Дополнительная информация здесь: http://www.danharman.net/2011/10/26/mongodb-ninjitsu-using-objectid-as-a-timestamp/

Ответ 4

См.

http://www.mongodb.org/display/DOCS/Object+IDs#ObjectIDs-DocumentTimestamps

Вероятно, однако, я всегда предпочел бы иметь выделенную метку времени вместо того, чтобы полагаться на некоторые такие внутренние элементы, такие как временная метка, каким-то образом встроенным в некоторый идентификатор объекта.

Ответ 5

От: http://www.mongodb.org/display/DOCS/Object+IDs#ObjectIDs-DocumentTimestamps

"в поле _id, которое хранит значения ObjectId, примерно эквивалентно сортировке по времени создания, хотя это отношение не является строгим с значениями ObjectId, сгенерированными на нескольких системах за одну секунду."

Ответ 6

Чтобы запросить проекты, созданные в течение 7 дней, robomongo, я использую ниже функцию:

db.getCollection('projects').find({
  $where: function() {
    // last 7 days
    return Date.now() - this._id.getTimestamp() < (7 * 24 * 60 * 60 * 1000)
  }
}).sort({
  '_id': -1
})