web-dev-qa-db-fra.com

utilise pour le temps de création de mongodb ObjectId

Le ObjectId utilisé comme clé par défaut dans les documents mongodb a un horodatage incorporé (l'appel objectid.generation_time renvoie un objet datetime). Il est donc possible d'utiliser ce temps de génération au lieu de conserver un horodatage de création distinct? Comment allez-vous pouvoir trier efficacement par heure de création ou interroger les N derniers éléments en utilisant cet horodatage intégré?

49
kefeizhou

Je suppose que MongoDB ObjectId contient un horodatage, vous pouvez trier par "date de création" si vous triez par objectId:

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

Et si vous voulez les 30 derniers éléments créés, vous pouvez utiliser la requête suivante:

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

Je ne suis vraiment pas sûr, je suppose simplement que la commande par _id devrait fonctionner comme décrit ci-dessus. Je créerai quelques tests plus tard.

Mise à jour:

Oui c'est vrai. Si vous commandez par _id, vous commanderez automatiquement par _id date de création. J'ai fait un petit test en c #, mb quelqu'un s'y intéresse:

  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);
   }
}
73
Andrew Orsich

Oui, vous pouvez utiliser le generation_time de BSON ObjectId aux fins que vous souhaitez. Alors,

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

renverra les 10 derniers éléments créés. Cependant, étant donné que les horodatages intégrés ont une précision d'une seconde, plusieurs éléments dans une seconde sont stockés dans l'ordre de leur création.

17
user105991

Le code pour convertir un DateTime en son horodatage correspondant avec le pilote c # est le suivant:

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

Plus d'informations ici: http://www.danharman.net/2011/10/26/mongodb-ninjitsu-using-objectid-as-a-timestamp/

3
DanH

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

"Le tri sur un champ _id qui stocke les valeurs ObjectId équivaut à peu près au tri par heure de création, bien que cette relation ne soit pas stricte avec les valeurs ObjectId générées sur plusieurs systèmes en une seule seconde."

2
wprl

Pour interroger des projets créés dans les 7 jours, j'utilise l'extrait ci-dessous:

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

et si vous souhaitez obtenir des éléments avec des champs spécifiés:

db.getCollection('projects').find({
  $where: function() {
    // last 7 days
    return Date.now() - this._id.getTimestamp() < (7 * 24 * 60 * 60 * 1000)
  }
}).sort({
  '_id': -1
}).toArray().map(function(item) {
  var res = {};
  res['Project Name'] = item.config.label;
  res['Author'] = item.author;
  res['Created At'] = item._id.getTimestamp().toLocaleDateString();
  res['Last Modified Date'] = item.config.lastModifDate.toLocaleString();
  return res;
});

il renverra quelque chose comme ceci:

[{
  "Project Name": "Newsletter",
  "Author": "larry.chen",
  "Created At": "Thursday, January 19, 2017",
  "Last Modified Date": "Thursday, January 19, 2017 17:05:40"
}...]

PS: le logiciel que j'utilise pour me connecter à MongoDB est Robo 3T

J'espère que ceci vous aidera.

1
Chen Dachao

Voir

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

Probablement faisable, cependant, je préférerais toujours avoir un horodatage dédié au lieu de compter sur certains éléments internes tels que l'horodatage en quelque sorte intégré dans un identifiant d'objet.

1
Andreas Jung