Come faccio a rendere Perl Mongo Trova () restituire i record in cui TS è inferiore a 5 giorni?

StackOverflow https://stackoverflow.com//questions/22084245

  •  24-12-2019
  •  | 
  •  

Domanda

Ho una collezione mongodb chiamata ClickStream e vuoi trovare tutti i documenti che corrispondono a un pubcode specifico con un timestamp negli ultimi 5 giorni. Il timestamp è in un campo chiamato TS, con un tipo di data del MONGO.

Dal guscio mongo posso eseguire quanto segue: -

    db.Clickstream.find({
        pubCode : "w_abc123",
        ts: {$gte: ISODate("2014-02-28T00:00:00Z")}
    })
.

Tuttavia, non riesco a sembrare la stessa cosa in Perl (usando la data di oggi, piuttosto che una data e un tempo hardcoded).Se lo faccio: -

    my $now = DateTime->now;
    my $n_days_ago = $now->add( days => -5 );
    ... etc ...
    my $ptr = $ptrClickstream->find(
        {
            pubCode => "$pubCode",
            ts => { "\$gte" => ISODate("$n_days_ago") }
        }, 
        { hitType => 1 }
    );
.

ottengo il seguente messaggio di errore: -

Sottoroutine non definita e principale :: Isorode chiamato a ricalcpubpop.pm Line 25.

e se rimuovo il riferimento a Isodata () come questo

    my $ptr = $ptrClickstream->find({
        pubCode => "$pubCode", ts => { "\$gte" => "$n_days_ago" }
    });
.

Non ottengo documenti restituiti.

Qualche suggerimento su come rendere questa scoperta () restituire i record in cui TS è inferiore a 5 giorni? Grazie!

È stato utile?

Soluzione

Usa Datetime naturalmente. Semplicemente spiegando per interezza.

Allora, dove si vede quella forma di ISODate dall'interno del guscio del mongo, che è in realtà solo una rappresentazione nativa per l'ambiente JavaScript di Shell della Data BSON sottostante che è davvero memorizzata.

Come tale, il driver perl "gonfia" questi valori come datetime oggetti quando li recupera, e in modo simile gestisce la conversione alla data BSON quando si passa nei valori.

Quindi hai già fatto il datetime matematica parte Il tuo codice:

my $now = DateTime->now;
my $n_days_ago = $now->add( days => -5 );
.

Per riferimento ->add funziona "sul posto" e sembri volere la "partenza" del giorno in modo che possiamo troncare.

Prova a forzare le date "UTC", che è ciò che saranno nella collezione che è solo per completezza mentre generalmente dovrebbero essere in quel modo. È possibile trovare questo modulo di codifica della tua data un po 'più pulito:

my $then = DateTime->now( time_zone => 'UTC' )
             ->truncate( to => 'day' )->add( days => -5 );
.

E la tua seconda forma di query è stata generalmente giusta, ma il tuo problema reale Real Sei stato a coercizione alla stringa interpolando come in "$n_days_ago", quindi non hai avuto l'oggetto ma la stringa. Vedi il modulo come ho modificato e non cercare di interpolare a meno che tu non intendi davvero:

my $ptr = $ptrClickstream->find({
    pubCode => $pubCode, ts => { '$gte' => $then } 
});
.

Quindi tutto questo funziona per me. Se ciò non restituisce un risultato controlla il tuo vars che i loro valori sono sicuramente ciò che ti aspetti.

Tutte le implementazioni del conducente gestiscono "Oggetti Data" nativi "per la loro lingua in questo modo.

Per ulteriori informazioni, consultare la sezione Driver su Date .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top