3

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 ドライバーを介してリテラル コマンドを渡す方法を理解できませんでした。

4

1 に答える 1

4

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

Connection の起動時に、必要な Date オブジェクトを設定することもできます。

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

たとえば、DateTime::Tiny に設定すると、より高速になります。しかし、まず DateTime と DateTime::Tiny の違いを理解する必要があります。ブースのドキュメントを読んで、どちらが優れているかを判断してください。


上記の例は、クライアント時間を作成します。クライアント/サーバーは同じではないため、クライアントではなくサーバーからの時間が必要な場合。できることは 2 つあります。

最初に、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),
});

2番目の可能性。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
于 2012-12-14T12:39:53.947 に答える