node.js - example - mongoose tutorial español
MongoDB/Mongoose preguntando en una fecha específica? (6)
Para aquellos de nosotros que usamos Moment.js
var moment = require(''moment'')
var today = moment().startOf(''day'')
var tomorrow = moment(today).add(1, ''days'')
MyModel.find({
createdAt: {
$gte: today.toDate(),
$lt: tomorrow.toDate()
}
})
Importante: todos los momentos son mutables
tomorrow = today.add(1, ''days'')
no funciona ya que también muta today
. El moment(today)
llamar moment(today)
resuelve ese problema clonando implícitamente today
.
¿Es posible consultar una fecha específica?
Encontré en el libro de cocina de mongo que podemos hacerlo por un rango. Consultando por un rango de fechas como ese:
db.posts.find({"created_on": {"$gte": start, "$lt": end}})
Pero, ¿es posible una fecha específica? Esto no funciona:
db.posts.find({"created_on": new Date(2012, 7, 14) })
Eso debería funcionar si las fechas que guardó en el DB son sin tiempo (solo día, mes, año).
Lo más probable es que las fechas que guardó fueran new Date()
, que incluye los componentes de tiempo. Para consultar esos momentos, necesita crear un intervalo de fechas que incluya todos los momentos de un día.
db.posts.find( //query today up to tonight
{"created_on": {"$gte": new Date(2012, 7, 14), "$lt": new Date(2012, 7, 15)}})
Has probado:
db.posts.find({"created_on": {"$gte": new Date(2012, 7, 14), "$lt": new Date(2012, 7, 15)}})
El problema con el que se encontrará es que las fechas se almacenan como marcas de tiempo en Mongo. Por lo tanto, para que coincida con una fecha, le pedirá que coincida con una marca de tiempo. En su caso, creo que está tratando de hacer coincidir un día (es decir, de 00:00 a 23:59 en una fecha específica). Si sus fechas están almacenadas sin tiempo, entonces debería estar bien. De lo contrario, intente especificar su fecha como un rango de tiempo en el mismo día (es decir, start = 00: 00, end = 23: 59) si gte no funciona.
Puede usar el siguiente enfoque para el método API para obtener resultados del día específico:
# [HTTP GET]
getMeals: (req, res) ->
options = {}
# eg. api/v1/meals?date=Tue+Jan+13+2015+00%3A00%3A00+GMT%2B0100+(CET)
if req.query.date?
date = new Date req.query.date
date.setHours 0, 0, 0, 0
endDate = new Date date
endDate.setHours 23, 59, 59, 59
options.date =
$lt: endDate
$gte: date
Meal.find options, (err, meals) ->
if err or not meals
handleError err, meals, res
else
res.json createJSON meals, null, ''meals''
Sí, el objeto Date compila la fecha y la hora, por lo tanto, compararlo con el valor de fecha solo no funciona.
Simplemente puede usar el operador $where para expresar una condición más compleja con la expresión booleana de Javascript :)
db.posts.find({ ''$where'': ''this.created_on.toJSON().slice(0, 10) == "2012-07-14"'' })
created_on
es el campo de fecha y hora y 2012-07-14
es la fecha especificada.
La fecha debe ser exactamente en formato AAAA-MM-DD .
Nota: Use $where
escasamente, tiene implicaciones de rendimiento.
Tuvimos un problema relacionado con la duplicación de datos en nuestra base de datos, con un campo de fecha que tenía varios valores en los que se suponía que teníamos 1. Pensé que agregaría la forma en que resolvimos el problema como referencia.
Tenemos una colección llamada "datos" con un campo numérico de "valor" y un campo de fecha "fecha". Tuvimos un proceso que pensamos que era idempotente, pero terminamos agregando 2 x valores por día en la segunda ejecución:
{ "_id" : "1", "type":"x", "value":1.23, date : ISODate("2013-05-21T08:00:00Z")}
{ "_id" : "2", "type":"x", "value":1.23, date : ISODate("2013-05-21T17:00:00Z")}
Solo necesitamos 1 de los 2 registros, así que tuvimos que recurrir a javascript para limpiar el db. Nuestro enfoque inicial fue iterar a través de los resultados y eliminar cualquier campo con un tiempo de entre 6am y 11am (todos los duplicados fueron en la mañana), pero durante la implementación, se realizó un cambio. Aquí está el script utilizado para solucionarlo:
var data = db.data.find({"type" : "x"})
var found = [];
while (data.hasNext()){
var datum = data.next();
var rdate = datum.date;
// instead of the next set of conditions, we could have just used rdate.getHour() and checked if it was in the morning, but this approach was slightly better...
if (typeof found[rdate.getDate()+"-"+rdate.getMonth() + "-" + rdate.getFullYear()] !== "undefined") {
if (datum.value != found[rdate.getDate()+"-"+rdate.getMonth() + "-" + rdate.getFullYear()]) {
print("DISCREPENCY!!!: " + datum._id + " for date " + datum.date);
}
else {
print("Removing " + datum._id);
db.data.remove({ "_id": datum._id});
}
}
else {
found[rdate.getDate()+"-"+rdate.getMonth() + "-" + rdate.getFullYear()] = datum.value;
}
}
y luego lo ejecutó con mongo thedatabase fixer_script.js