简体   繁体   English

从Perl驱动程序插入MongoDB服务器日期

[英]Insert MongoDB Server Date from Perl driver

From the MongoDB console, I can: 从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") } 

How can I do the same from the Perl MongoDB driver? 如何从Perl MongoDB驱动程序中执行相同的操作?

Background 背景

I am using MongoDB with a capped collection for logging. 我使用带有上限集合的MongoDB进行日志记录。 I understand that the ObjectID contains a timestamp, but displaying it and querying it is not simple. 我知道ObjectID包含一个时间戳,但显示它并查询它并不简单。 I would therefore like to add a server-based timestamp to each entry, but have been unable to figure out how to pass literal commands via the Perl driver. 因此,我想为每个条目添加基于服务器的时间戳,但是无法弄清楚如何通过Perl驱动程序传递文字命令。

The Perl MongoDB Driver uses DateTime objects to store Dates, and returns DateTime object back to you if you read dates from the database. 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");
}

If you execute it, it prints something like 如果你执行它,它会打印出像

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

You should also read the DateTime Documentation to understand what you can do with it: http://search.cpan.org/perldoc?DateTime 您还应该阅读DateTime文档以了解您可以使用它做什么: http ://search.cpan.org/perldoc?DateTime

On the Connection startup you can also set which Date object you want. 在Connection启动时,您还可以设置所需的Date对象。

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

If you set it to DateTime::Tiny for example it will be faster. 如果你将它设置为DateTime :: Tiny,例如它会更快。 But you should first understand the difference between DateTime and DateTime::Tiny. 但是你应该首先理解DateTime和DateTime :: Tiny之间的区别。 Read the Documentation of booth and decide in which case the one or the other is better. 阅读展位的文档,并决定哪一个更好。


The example above creates the client time. 上面的示例创建了客户端时间。 If you want the time from the server instead of your client, because client/server are not the same. 如果您想从服务器而不是客户端获得时间,因为客户端/服务器不一样。 You can do two things. 你可以做两件事。

At first, create a JavaScript function that returns a Date object und evaluate the function on the server. 首先,创建一个JavaScript函数,该函数返回Date对象并评估服务器上的函数。

# 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),
});

The second possibility. 第二种可能性。 The default "_id" object from MongoDB already contains a timestamp when the object will be created. MongoDB中的默认“_id”对象已经包含创建对象时的时间戳。 At least the documentation says it comes from the server, and i hope it really comes from the server and will not created by the driver. 至少文档说它来自服务器,我希望它真的来自服务器,不会由驱动程序创建。 But if $entry is your MongoDB result you can get a DateTime object from it this way: 但是如果$ entry是你的MongoDB结果,你可以通过这种方式从它获取一个DateTime对象:

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

Example: 例:

#!/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";
}

Output: 输出:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM