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é?
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);
}
}
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.
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/
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."
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.
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.