web-dev-qa-db-fra.com

Trouver des objets entre deux dates MongoDB

Je me suis amusé à stocker des tweets dans mongodb, chaque objet ressemble à ceci:

{
"_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
}

Comment puis-je écrire une requête qui vérifie le created_at et trouve tous les objets entre 18h47 et 19h00? Dois-je mettre à jour mes documents pour que les dates soient stockées dans un format spécifique?

348
Tom

interrogation d'une plage de dates (mois ou jour spécifique) dans le Livre de recettes MongoDB a une très bonne explication à ce sujet, mais ci-dessous, j’ai essayé moi-même et cela semble fonctionner.

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)" }

Sur la base de mes expériences, vous devrez sérialiser vos dates dans un format pris en charge par MongoDB, car les résultats de recherche suivants ont été indésirables.

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" }

Dans le deuxième exemple, aucun résultat n'était attendu, mais il en restait un. En effet, une comparaison de chaîne de base est effectuée.

539
ponzao

Clarifier. Ce qui est important à savoir, c'est que:

  • Oui, vous devez passer un objet Date Javascript.
  • Oui, il faut que ce soit convivial
  • Oui, d'après mon expérience, il est nécessaire de manipuler la date à l'ISO.
  • Oui, travailler avec des dates est généralement un processus fastidieux, et mongo ne fait pas exception

Voici un extrait de code fonctionnel dans lequel nous effectuons un peu de manipulation de date pour nous assurer que Mongo (ici, j'utilise un module mangouste et souhaite obtenir des résultats pour les lignes dont l'attribut de date est inférieur à la date indiquée sous myDate param). il correctement:

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

MongoDB stocke en fait les millis d'une date sous la forme d'un entier (64), comme prescrit par http://bsonspec.org/#/specification

Cependant, cela peut être assez déroutant lorsque vous récupérez des dates car le pilote client instanciera un objet de date avec son propre fuseau horaire local. Le pilote JavaScript de la console mongo le fera certainement.

Donc, si vous vous souciez de votre fuseau horaire, assurez-vous de savoir ce qu’il est censé être quand vous le récupérerez. Cela ne devrait pas avoir autant d'importance pour les requêtes, car cela correspondra toujours au même int (64), quel que soit le fuseau horaire de votre objet de date (j'espère). Mais je ferais certainement des requêtes avec des objets de date réels (pas de chaînes) et laisserais le pilote faire son travail.

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

Remplacez collection par le nom de la collection sur laquelle vous souhaitez exécuter la requête

12
GSK

Python et pymongo

Recherche d'objets entre deux dates dans Python avec pymongo dans la collection posts (d'après le 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)

{"$gte": from_date, "$lt": to_date} spécifie la plage en termes de types datetime.datetime.

9
Anton Tarasenko

Utilisez ce code pour rechercher l'enregistrement entre deux dates à l'aide de $gte et $lt:

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

Utilisation de Moment.js et opérateurs de requête de comparaison

  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) { ... });
3
Tính Ngô Quang

Convertissez vos dates en fuseau horaire GMT au fur et à mesure que vous les collez dans Mongo. De cette façon, il n'y a jamais de problème de fuseau horaire. Ensuite, faites le calcul sur le champ Twitter/timezone lorsque vous extrayez les données pour les présenter.

2
heregear

Pourquoi ne pas convertir la chaîne en un entier de la forme AAAAMMJJHHMMSS? Chaque incrément de temps créerait alors un entier plus grand, et vous pouvez filtrer sur les entiers au lieu de vous inquiéter de la conversion en temps ISO.

2
ZacharyST

utilisez $ gte et $ lte pour trouver entre les données de date dans 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

j'ai essayé dans ce modèle selon mes besoins j'ai besoin de stocker une date chaque fois qu'un objet est créé plus tard je veux récupérer tous les enregistrements (documents) entre deux dates dans mon fichier html J'utilisais le format suivant: mm/jj/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>

dans mon fichier py (python) je l'ai converti en "iso fomate" de la manière suivante

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

et enregistré dans ma collection dbmongo avec "SelectedDate" comme champ dans ma collection

pour récupérer des données ou des documents entre deux dates, j'ai utilisé la requête suivante

db.collection.find( "SelectedDate": {'$gte': SelectedDate1,'$lt': SelectedDate2}})
0
ayu for u
mongoose.model('ModelName').aggregate([
    {
        $match: {
            userId: mongoose.Types.ObjectId(userId)
        }
    },
    {
        $project: {
            dataList: {
              $filter: {
                 input: "$dataList",
                 as: "item",
                 cond: { 
                    $and: [
                        {
                            $gte: [ "$$item.dateTime", new Date(`2017-01-01T00:00:00.000Z`) ]
                        },
                        {
                            $lte: [ "$$item.dateTime", new Date(`2019-12-01T00:00:00.000Z`) ]
                        },
                    ]
                 }
              }
           }
        }
     }
])
0
Jitendra