![](/img/trans.png)
[英]How do I find a date which is three days earlier than a given date in Perl?
[英]How do I make Perl Mongo find() return the records where ts is less than 5 days old?
我有一个名为Clickstream的MongoDB集合,并且希望查找最近5天内与特定pubCode匹配并带有时间戳的所有文档。 时间戳记在一个名为ts的字段中,其Mongo数据类型为Date。
在Mongo Shell中,我可以执行以下操作:
db.Clickstream.find({
pubCode : "w_abc123",
ts: {$gte: ISODate("2014-02-28T00:00:00Z")}
})
但是,我似乎无法在Perl中做同样的事情(使用今天的日期,而不是硬编码的日期和时间)。 如果我这样做:
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 }
);
我收到以下错误消息:
在recalcPubPop.pm第25行调用了未定义的子例程&main :: ISODate。
如果我像这样删除对ISOData()的引用
my $ptr = $ptrClickstream->find({
pubCode => "$pubCode", ts => { "\$gte" => "$n_days_ago" }
});
我没有退回任何文件。
关于如何使此find()返回ts小于5天的记录的任何建议? 谢谢!
自然使用DateTime 。 仅作整体解释。
因此,在mongo shell中看到ISODate
表单的地方,它实际上只是底层BSON Date的shell JavaScript环境的本机表示形式,而该环境实际上已存储。
这样,Perl驱动程序在检索它们时会将这些值“膨胀”为DateTime对象,并在传递这些值时以类似的方式处理对BSON日期的转换。
因此,您已经在代码中完成了DateTime数学部分:
my $now = DateTime->now;
my $n_days_ago = $now->add( days => -5 );
供参考->add
可以“就地”运行,您似乎想要一天的“开始”以便我们截断。
尝试并强制使用“ UTC”日期,这将是它们在集合中的日期,这只是出于完整性的考虑,通常应采用这种方式。 您可能会发现这种形式的日期编码更简洁:
my $then = DateTime->now( time_zone => 'UTC' )
->truncate( to => 'day' )->add( days => -5 );
第二种查询形式通常是正确的,但是真正的问题是您要像"$n_days_ago"
那样通过插值来强制字符串,因此您没有对象,只有字符串。 请参阅我修改过的表格,除非您确实要这样做,否则不要尝试插值:
my $ptr = $ptrClickstream->find({
pubCode => $pubCode, ts => { '$gte' => $then }
});
因此,所有这些对我都有效。 如果没有返回结果,请检查您的vars
,确定它们的值绝对是您期望的值。
所有驱动程序实现都以这种方式为其语言处理本地“日期对象”。
有关更多信息,请参见日期上的驱动程序部分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.