autoincrement - usos para mongodb ObjectId tiempo de creación
mongoose objectid (6)
El ObjectId
utilizado como la clave predeterminada en los documentos de mongodb tiene una marca de tiempo incrustada (al llamar a objectid.generation_time devuelve un objeto de fecha y hora). Entonces, ¿es posible usar este tiempo de generación en lugar de mantener una marca de tiempo de creación por separado? ¿Cómo podrá ordenar por tiempo de creación o consultar los últimos N elementos de manera eficiente utilizando esta marca de tiempo incrustada?
De: http://www.mongodb.org/display/DOCS/Object+IDs#ObjectIDs-DocumentTimestamps
"ordenar en un campo _id que almacena valores de ObjectId es más o menos equivalente a ordenar por tiempo de creación, aunque esta relación no es estricta con los valores de ObjectId generados en múltiples sistemas en un solo segundo".
El código para convertir un DateTime a su marca de tiempo correspondiente con el controlador c # es el siguiente:
public static ObjectId ToObjectId(this DateTime dateTime)
{
var timestamp = (int)(dateTime - BsonConstants.UnixEpoch).TotalSeconds;
return new ObjectId(timestamp, 0, 0, 0);
}
Más información aquí: http://www.danharman.net/2011/10/26/mongodb-ninjitsu-using-objectid-as-a-timestamp/
Para consultar proyectos creados en 7 días, utilizo el siguiente fragmento:
db.getCollection(''projects'').find({
$where: function() {
// last 7 days
return Date.now() - this._id.getTimestamp() < (7 * 24 * 60 * 60 * 1000)
}
}).sort({
''_id'': -1
})
y si desea obtener elementos con campos especificados:
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;
});
Devolverá algo como esto:
[{
"Project Name": "Newsletter",
"Author": "larry.chen",
"Created At": "Thursday, January 19, 2017",
"Last Modified Date": "Thursday, January 19, 2017 17:05:40"
}...]
PD: el software que uso para conectarme a MongoDB es Robo 3T
Espero que esto te ayudará.
Sí, puede usar generation_time de BSON ObjectId para los fines que desee. Asi que,
db.collection.find().sort({ _id : -1 }).limit(10)
devolverá los últimos 10 elementos creados. Sin embargo, dado que las marcas de tiempo incorporadas tienen una precisión de un segundo, los elementos múltiples dentro de cualquier segundo se almacenan en el orden de su creación.
Supongo que, dado que MongoDB ObjectId contiene una marca de tiempo, puede ordenar por ''fecha de creación'' si va a ordenar por objectId:
items.find.sort( [[''_id'', -1]] ) // get all items desc by created date.
Y si desea los últimos 30 elementos creados, puede usar la siguiente consulta:
items.find.sort( [[''_id'', -1]] ).limit(30) // get last 30 createad items
Realmente no estoy seguro, solo supongo que ordenar por _id debería funcionar como se describe arriba. Crearé algunas pruebas más tarde.
Actualizar:
Sí, así es. Si ordena por _id, ordenará automáticamente antes de _id fecha de creación. He hecho una pequeña prueba en c #, mb a alguien le interesa:
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);
}
}
Ver
http://www.mongodb.org/display/DOCS/Object+IDs#ObjectIDs-DocumentTimestamps
Probablemente factible, sin embargo, siempre preferiría tener una marca de tiempo dedicada en lugar de confiar en algunos elementos internos, como la marca de tiempo de alguna manera incrustado en algún identificador de objeto.