【问题标题】:Insert MongoDB Server Date from Perl driver从 Perl 驱动程序插入 MongoDB 服务器日期
【发布时间】:2014-07-28 06:01:40
【问题描述】:

从 MongoDB 控制台,我可以:

>  db.log.insert({ dt : new Date })
>  db.log.find().sort({ $natural : -1 }).limit(1)
{ "_id" : ObjectId("50caae2cadd0e471af0b3941"), "dt" : ISODate("2012-12-14T04:42:20.560Z") } 

如何通过 Perl MongoDB 驱动程序执行相同的操作?

背景

我正在使用带有上限集合的 MongoDB 进行日志记录。我了解 ObjectID 包含时间戳,但显示和查询它并不简单。因此,我想为每个条目添加一个基于服务器的时间戳,但一直无法弄清楚如何通过 Perl 驱动程序传递文字命令。

【问题讨论】:

  • @KarthikT 这只是基本教程的链接。我无法在那里找到解决方案 - 请您指出正确的方向吗?
  • 对不起,我没有使用 MongoDB 的经验,但 this 有帮助吗?它谈到了将 shell 命令翻译成 perl 代码
  • @KarthikT 谢谢,但我也找不到从 JS 函数中设置值的方法。看起来我想做的事情在 PHP 中很简单:MongoDate :-(

标签: perl mongodb


【解决方案1】:

Perl MongoDB 驱动程序使用 DateTime 对象来存储日期,如果您从数据库中读取日期,则将 DateTime 对象返回给您。

#!/usr/bin/env perl
use strict;
use warnings;
use MongoDB;
use MongoDB::OID;
use DateTime;

# database connection & collection
my $conn  = MongoDB::Connection->new;
my $db    = $conn->dates;
my $log   = $db->log;

# Delete Collection
$log->drop;

# Insert one
my $oid = $log->insert({ dt => DateTime->now });

# Show all
my $all = $log->find;
while ( my $entry = $all->next ) {
    printf "_id: %s dt: %s\n", $entry->{_id}->to_string, $entry->{dt}->format_cldr("dd.MM.yyyy HH:mm:ss");
}

如果你执行它,它会打印出类似的东西

_id: 50cb1b9321d30efd17000000 dt: 14.12.2012 12:29:07

您还应该阅读 DateTime 文档以了解您可以使用它做什么:http://search.cpan.org/perldoc?DateTime

在连接启动时,您还可以设置所需的日期对象。

http://search.cpan.org/perldoc?MongoDB::Connection#dt_type

例如,如果您将其设置为 DateTime::Tiny,它会更快。但是您应该首先了解 DateTime 和 DateTime::Tiny 之间的区别。阅读展位文档并决定哪种情况更好。


上面的例子创建了客户端时间。如果您想要来自服务器而不是客户端的时间,因为客户端/服务器不一样。你可以做两件事。

首先,创建一个返回 Date 对象的 JavaScript 函数并在服务器上评估该函数。

# JavaScript function that return a Date object
my $now = MongoDB::Code->new(code => qq{function(){
    return new Date
}});

# later...
my $oid = $log->insert({ 
    dt => $dt,
    st => $db->eval($now),
});

第二种可能。 MongoDB 的默认“_id”对象已经包含创建对象时的时间戳。至少文档说它来自服务器,我希望它真的来自服务器并且不会由驱动程序创建。但是如果 $entry 是您的 MongoDB 结果,您可以通过这种方式从中获取 DateTime 对象:

my $dt = DateTime->from_epoch(epoch => $entry->{_id}->get_time);

例子:

#!/usr/bin/env perl
use strict;
use warnings;
use MongoDB;
use MongoDB::OID;
use MongoDB::Code;
use DateTime;

# database connection & collection
my $conn  = MongoDB::Connection->new;
my $db    = $conn->dates;
my $log = $db->log;

# Delete Collection
$log->drop;

# Client Time
my $dt = DateTime->now;

# JavaScript function that return a Date object
my $now = MongoDB::Code->new(code => qq{function(){
    return new Date
}});

# wait 2 seconds to see a difference between
# $dt and the $now function
sleep 2;

# Insert one
$log->insert({ 
    dt => $dt,
    st => $db->eval($now),
});

sleep 2;

$log->insert({ 
    dt => $dt,
    st => $db->eval($now),
});

# Show all
my $dtf = "dd.MM.yyyy HH:mm:ss";
my $all = $log->find;
while ( my $entry = $all->next ) {
    printf "dt: %s\n", $entry->{dt}->format_cldr($dtf);
    printf "st: %s\n", $entry->{st}->format_cldr($dtf);
    printf "_id time: %s\n", DateTime->from_epoch(epoch => $entry->{_id}->get_time)->format_cldr($dtf);
    print "\n";
}

输出:

dt: 14.12.2012 16:29:28
st: 14.12.2012 16:29:30
_id time: 14.12.2012 16:29:30

dt: 14.12.2012 16:29:28
st: 14.12.2012 16:29:32
_id time: 14.12.2012 16:29:32

【讨论】:

  • 您好,感谢您的回复。您的示例是否没有将客户端日期发送到 MongoDB 服务器?我想使用服务器的日期 - 例如,我将在 MySQL 语句中使用 NOW()
  • 是的,现在是客户端时间。我在答案中添加了一些代码,您如何实现“NOW()”之类的东西。
  • 酷!我非常接近自己的尝试——我想出了 JavaScript 函数,但我错过了 eval() 方法。我刚刚得到了一个字符串化的函数。感谢您抽出宝贵时间做出如此详细的回复。
猜你喜欢
  • 2015-05-13
  • 1970-01-01
  • 2018-09-19
  • 1970-01-01
  • 2016-09-20
  • 2017-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多