it-swarm-es.com

Encuentra objetos entre dos fechas MongoDB

He estado jugando a almacenar tweets dentro de mongodb, cada objeto se parece a esto:

{
"_id" : ObjectId("4c02c58de500fe1be1000005"),
"contributors" : null,
"text" : "Hello world",
"user" : {
    "following" : null,
    "followers_count" : 5,
    "utc_offset" : null,
    "location" : "",
    "profile_text_color" : "000000",
    "friends_count" : 11,
    "profile_link_color" : "0000ff",
    "verified" : false,
    "protected" : false,
    "url" : null,
    "contributors_enabled" : false,
    "created_at" : "Sun May 30 18:47:06 +0000 2010",
    "geo_enabled" : false,
    "profile_sidebar_border_color" : "87bc44",
    "statuses_count" : 13,
    "favourites_count" : 0,
    "description" : "",
    "notifications" : null,
    "profile_background_tile" : false,
    "lang" : "en",
    "id" : 149978111,
    "time_zone" : null,
    "profile_sidebar_fill_color" : "e0ff92"
},
"geo" : null,
"coordinates" : null,
"in_reply_to_user_id" : 149183152,
"place" : null,
"created_at" : "Sun May 30 20:07:35 +0000 2010",
"source" : "web",
"in_reply_to_status_id" : {
    "floatApprox" : 15061797850
},
"truncated" : false,
"favorited" : false,
"id" : {
    "floatApprox" : 15061838001
}

¿Cómo escribiría una consulta que verifique el created_at y encuentre todos los objetos entre las 18:47 y las 19:00? ¿Necesito actualizar mis documentos para que las fechas se almacenen en un formato específico?

332
Tom

Consultar por un intervalo de fechas (mes o día específico) en el Libro de cocina de MongoDB Tiene una muy buena explicación al respecto, pero a continuación hay algo que probé y que parece funcionar.

items.save({
    name: "example",
    created_at: ISODate("2010-04-30T00:00:00.000Z")
})
items.find({
    created_at: {
        $gte: ISODate("2010-04-29T00:00:00.000Z"),
        $lt: ISODate("2010-05-01T00:00:00.000Z")
    }
})
=> { "_id" : ObjectId("4c0791e2b9ec877893f3363b"), "name" : "example", "created_at" : "Sun May 30 2010 00:00:00 GMT+0300 (EEST)" }

Según mis experimentos, deberá serializar sus fechas en un formato compatible con MongoDB, ya que lo siguiente dio resultados de búsqueda no deseados.

items.save({
    name: "example",
    created_at: "Sun May 30 18.49:00 +0000 2010"
})
items.find({
    created_at: {
        $gte:"Mon May 30 18:47:00 +0000 2015",
        $lt: "Sun May 30 20:40:36 +0000 2010"
    }
})
=> { "_id" : ObjectId("4c079123b9ec877893f33638"), "name" : "example", "created_at" : "Sun May 30 18.49:00 +0000 2010" }

En el segundo ejemplo no se esperaban resultados, pero aún se obtuvo uno. Esto se debe a que se realiza una comparación de cadena básica.

505
ponzao

Para aclarar. Lo que es importante saber es que:

  • Sí, tienes que pasar un objeto de fecha de Javascript.
  • Sí, tiene que ser ISODate amigable
  • Sí, por mi experiencia para que esto funcione, es necesario manipular la fecha a ISO
  • Sí, trabajar con fechas suele ser siempre un proceso tedioso, y mongo no es una excepción

Aquí hay un fragmento de código de trabajo, donde hacemos un poco de manipulación de fechas para asegurarnos de que Mongo (aquí estoy usando el módulo de mangosta y quiero resultados para las filas cuyo atributo de fecha sea menor que (antes) la fecha dada como mi fecha de parametrización) puede manejar correctamente

var inputDate = new Date(myDate.toISOString());
MyModel.find({
    'date': { $lte: inputDate }
})
25
arcseldon

MongoDB realmente almacena los milis de una fecha como un int (64), según lo prescrito en http://bsonspec.org/#/specification

Sin embargo, puede ser bastante confuso cuando recupera fechas, ya que el controlador del cliente creará una instancia de un objeto de fecha con su propia zona horaria local. El controlador de JavaScript en la consola mongo sin duda hará esto.

Entonces, si te importan tus zonas horarias, asegúrate de saber qué se supone que debe ser cuando lo recuperes. Esto no debería importar tanto para las consultas, ya que aún será igual a la misma int (64), independientemente de la zona horaria en la que se encuentre su objeto de fecha (espero). Pero definitivamente haría consultas con objetos de fecha reales (no cadenas) y dejaría que el conductor haga su trabajo.

16
Ben Smith
db.collection.find({"createdDate":{$gte:new ISODate("2017-04-14T23:59:59Z"),$lte:new ISODate("2017-04-15T23:59:59Z")}}).count();

Reemplace collection con el nombre de la colección que desea ejecutar la consulta

8
GSK

Python y pymongo

Encontrar objetos entre dos fechas en Python con pymongo en la colección posts (basada en el tutorial ):

from_date = datetime.datetime(2010, 12, 31, 12, 30, 30, 125000)
to_date = datetime.datetime(2011, 12, 31, 12, 30, 30, 125000)

for post in posts.find({"date": {"$gte": from_date, "$lt": to_date}}):
    print(post)

Donde {"$gte": from_date, "$lt": to_date} especifica el rango en términos de datetime.datetime types.

8
Anton Tarasenko

Use este código para encontrar el registro entre dos fechas usando $gte y $lt:

db.CollectionName.find({"whenCreated": {
    '$gte': ISODate("2018-03-06T13:10:40.294Z"),
    '$lt': ISODate("2018-05-06T13:10:40.294Z")
}});
5
Sunil Pal

Convierte tus fechas a la zona horaria GMT mientras las metes en Mongo. De esa manera nunca hay un problema de zona horaria. Luego simplemente haga los cálculos en el campo de zona horaria/Twitter cuando saque los datos para su presentación.

2
heregear

Usando con Moment.js y Operadores de consultas de comparación

  var today = moment().startOf('day');
  // "2018-12-05T00:00:00.00
  var tomorrow = moment(today).endOf('day');
  // ("2018-12-05T23:59:59.999

  Example.find(
  {
    // find in today
    created: { '$gte': today, '$lte': tomorrow }
    // Or greater than 5 days
    // created: { $lt: moment().add(-5, 'days') },
  }), function (err, docs) { ... });
2
TinhNQ

¿Por qué no convertir la cadena a un número entero de la forma YYYYMMDDHHMMSS? Cada incremento de tiempo crearía un entero más grande, y puede filtrar los enteros en lugar de preocuparse por la conversión al tiempo ISO.

2
ZacharyST

use $ gte y $ lte para buscar datos entre fechas en mongodb

var tomorrowDate = moment(new Date()).add(1, 'days').format("YYYY-MM-DD");
db.collection.find({"plannedDeliveryDate":{ $gte: new Date(tomorrowDate +"T00:00:00.000Z"),$lte: new Date(tomorrowDate + "T23:59:59.999Z")}})
1
KARTHIKEYAN.A

intenté en este modelo según mis requisitos. Necesito almacenar una fecha cada vez que se cree un objeto. Quiero recuperar todos los registros (documentos) entre dos fechas en mi archivo html. Estaba usando el siguiente formato mm/dd/aaaa

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>

    <script>
//jquery
    $(document).ready(function(){  
    $("#select_date").click(function() { 
    $.ajax({
    type: "post",
    url: "xxx", 
    datatype: "html",
    data: $("#period").serialize(),  
    success: function(data){
    alert(data);
    } ,//success

    }); //event triggered

    });//ajax
    });//jquery  
    </script>

    <title></title>
</head>

<body>
    <form id="period" name='period'>
        from <input id="selecteddate" name="selecteddate1" type="text"> to 
        <input id="select_date" type="button" value="selected">
    </form>
</body>
</html>

en mi archivo py (python) lo convertí en "iso fomate" de la siguiente manera

date_str1   = request.POST["SelectedDate1"] 
SelectedDate1   = datetime.datetime.strptime(date_str1, '%m/%d/%Y').isoformat()

y guardado en mi colección dbmongo con "SelectedDate" como campo en mi colección

para recuperar datos o documentos entre 2 fechas utilicé la siguiente consulta

db.collection.find( "SelectedDate": {'$gte': SelectedDate1,'$lt': SelectedDate2}})
0
ayu for u