Buscar objetos entre dos fechas MongoDB


He estado jugando almacenando tweets dentro de mongodb, cada objeto se ve así:

{
"_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 comprueba el created_at y encuentra todos los objetos entre 18:47 y 19:00? ¿Necesito actualizar mis documentos para que las fechas se almacenen en un formato específico?

Author: royhowie, 2010-05-31

10 answers

Consultar un Intervalo de Fechas (Mes o Día Específico) en el Libro de Cocina MongoDB tiene una muy buena explicación sobre el asunto, pero a continuación hay algo que probé yo mismo y 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)" }

Basado en mis experimentos necesitarás serializar tus fechas en un formato compatible con MongoDB, porque 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 todavía había uno conseguido. Esto se debe a que se realiza una comparación básica de cadenas.

 442
Author: ponzao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-02 13:54:20

Para aclarar. Lo que es importante saber es que:

  • Sí, tiene que pasar un objeto de fecha Javascript.
  • Sí, tiene que ser ISODate amable
  • Sí, por mi experiencia para que esto funcione, necesitas manipular la fecha a ISO
  • Sí, trabajar con fechas es generalmente 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 la fecha para garantizar Mongo (aquí estoy usando mongoose module and want results for rows whose date attribute is less than (before) the date given as myDate param) can handle it correctly:

var inputDate = new Date(myDate.toISOString());
MyModel.find({
    'date': { $lte: inputDate }
})
 19
Author: arcseldon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-30 15:34:18

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

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

Así que, si te preocupas por tus zonas horarias, asegúrate de saber lo que se supone que debe ser cuando lo recuperes. Esto no debería importar tanto mucho para las consultas, ya que todavía igualará 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 controlador hiciera lo suyo.

 16
Author: Ben Smith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-03 20:22:54
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

 6
Author: GSK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-07 01:01:59

Python y pymongo

Encontrar objetos entre dos fechas en Python con pymongo en la colección posts (basado 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 tipos datetime.datetime.

 5
Author: Anton Tarasenko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-16 13:24:33

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")
}});
 3
Author: Sunil Pal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-17 08:52:36

Convierta sus fechas a la zona horaria GMT mientras las está rellenando en Mongo. De esa manera nunca hay un problema de zona horaria. A continuación, simplemente haga los cálculos en el campo twitter / zona horaria cuando extraiga los datos para presentarlos.

 2
Author: heregear,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-26 14:24:23

¿Por qué no convertir la cadena a un 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 convertir a tiempo ISO.

 2
Author: ZacharyST,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-04 18:17:01

Probé en este modelo según mis requisitos necesito almacenar una fecha cuando se crea un objeto más tarde 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 las 2 fechas que utilicé siguiente consulta

db.collection.find( "SelectedDate": {'$gte': SelectedDate1,'$lt': SelectedDate2}})
 0
Author: ayu for u,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-04 11:29:29

Use get get y lt lt para encontrar 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"),$lt: new Date(tomorrowDate + "T23:59:59.999Z")}})
 0
Author: KARTHIKEYAN.A,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-07 12:53:56