ishiducaの日記 このページをアンテナに追加 RSSフィード

2010-09-22

[]手軽にMongoDBの任意のcollectionにアクセスするモジュール試行(錯誤) 21:40 手軽にMongoDBの任意のcollectionにアクセスするモジュール試行(錯誤) - ishiducaの日記 を含むブックマーク はてなブックマーク - 手軽にMongoDBの任意のcollectionにアクセスするモジュール試行(錯誤) - ishiducaの日記 手軽にMongoDBの任意のcollectionにアクセスするモジュール試行(錯誤) - ishiducaの日記 のブックマークコメント

手軽にMongoDBの任意のcollectionにアクセスするモジュールを試行錯誤している。

下の例だと MyMongoDBLite->new したPerlオブジェクトに

  • MongoDB::Connectionオブジェクト
  • MongoDB::Databaseオブジェクト
  • MongoDB::Collectionオブジェクト

を各々「ひとつ」格納していて、newしたPerlオブジェクトの「database」「collection」メソッドでget/setするようにしてみた

MyMongoDBLite.pm

package MyMongoDBLite;
use strict;
use warnings;
use MongoDB;

sub new {
    my $class = shift;
    my %args  = @_;

    $args{server} or $args{server} = 'localhost';
    $args{port}   or $args{port}   = '27017';

    my $mongodb = bless {}, $class;
    $mongodb->{connection} = MongoDB::Connection->new(
        server => $args{server}, port => $args{port} );

    if ($args{database}) {
        $mongodb->{database} =
            $mongodb->{connection}->get_database( $args{database} );

        if ($args{collection}) { 
            $mongodb->{collection} = 
                $mongodb->{database}->get_collection( $args{collection} );
        }
    }

    $mongodb;
}

sub database {
    my $self = shift;
    $self->connection or die qq(not found "connection".);
    if ($_[0]) {
        $self->{database} =
            $self->{connection}->get_database( $_[0] );
    }
    $self->{database};
}

sub collection {
    my $self = shift;
    $self->{database} or die qq(not found "database".);
    if ($_[0]) {
        $self->{collection} =
            $self->{database}->get_collection( $_[0] );
    }
    $self->{collection};
}

1;

例えば データベース "mydb" の "pixiv" コレクションにアクセスしてみる

get_pixiv_favorite_url.pl

use strict;
use warnings;
use MyMongoDBLite;

my $mongodb = MyMongoDBLite->new(
    server     => 'localhost',
    port       => '27017',
    database   => 'mydb',
    collection => 'pixiv'
);

my $query  = { link => qr/http/ };
my $cursor = $mongodb->collection->query( $query );
while (my $object = $cursor->next) {
    print "$object->{comment}\n";
}

exit 0;

ワンライナーでアクセスする

$ perl -MMyMongoDBLite -e 'print MyMongoDBLite->new(database => "mydb", collection => "pixiv")->collection->find_one({ link => qr/http/ })->{comment}'

とか

$ perl -MMyMongoDBLite -le '$c=MyMongoDBLite->new(database => "mydb")->collection("pixiv")->query({ link => qr/http/ });print $_->{comment} while $_ = $c->next;'

しかし、書き方に違和感が。本来なら

my $connection = MyMongoDBLite->new;
my $collection = $connection->database('mydb')->collection('pixiv');

となった方が自然だよね

トラックバック - http://perl.g.hatena.ne.jp/ishiduca/20100922

2010-09-17

[]MongoDBはじめてみました その3 13:32 MongoDBはじめてみました その3 - ishiducaの日記 を含むブックマーク はてなブックマーク - MongoDBはじめてみました その3 - ishiducaの日記 MongoDBはじめてみました その3 - ishiducaの日記 のブックマークコメント

まずは、Twitter検索で mongodb を含む結果を mydb.things コレクションに保存してみる

#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use URI;
use LWP::UserAgent;
use MongoDB;
use JSON;

my $uri = URI->new( 'http://search.twitter.com/search.json' );
$uri->query_form( "q" => 'mongodb' );

my $ua = LWP::UserAgent->new;
my $response = $ua->get( $uri );
$response->is_success or die $response->status_line;

my $json = decode_json( $response->{_content} );

my $connection = MongoDB::Connection->new( host => 'localhost', port => 27017 );
my $database   = $connection->mydb;
my $collection = $database->things;

for (@{$json->{results}}) {
    my $id   = $collection->insert($_);
}

exit 0;

次に、mydb.things コレクションに保存したデータ(Twitter検索で「mongodb」を含むツイートを保存したもの)から mongodb にマッチするハッシュを抜き出してみた。

MongoDB::Collection の find_one メソッドは、マッチしたドキュメント(ハッシュ)を返すので、ハッシュのプロパティを指定すれば、そのまま出力できるんだけど、 query メソッド(find メソッドと同じ)は Cursor オブジェクト(MongoDB::Cursorオブジェクト)を返すので、これをデータ(ハッシュ)に直してから処理をしないといけない。

search.pl

#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use Encode;
use MongoDB;
#use Data::Dumper;

my $connection = MongoDB::Connection->new( host => 'localhost', port => 27017 );
my $database   = $connection->mydb;
my $collection = $database->things;

#my $a_result = $collection->find_one( { text => qr/mongo/i } );
#print encode_utf8( $a_result->{text} );

my $cursor = $collection->query( { text => qr/mongodb/i } );

while (my $object = $cursor->next) {
    # print Dumper "$object\n";
    print encode_utf8( "$object->{text}\n" );
}

print "\n";
exit 0;

カーソルオブジェクトは、「クエリーとカーソル - Docs-Japanese - 10gen Confluence 」を参照しました。

トラックバック - http://perl.g.hatena.ne.jp/ishiduca/20100917

2010-09-16

[]MongoDBをはじめてみました その2の補足 21:28 MongoDBをはじめてみました その2の補足 - ishiducaの日記 を含むブックマーク はてなブックマーク - MongoDBをはじめてみました その2の補足 - ishiducaの日記 MongoDBをはじめてみました その2の補足 - ishiducaの日記 のブックマークコメント

MongoDBをはじめてみました その2」でfind_oneメソッドは正規表現も使えたんですね。

my $connection = MongoDB::Connection->new( host => 'localhost', port => 27017 );
my $database   = $connection->mydb;
my $collection = $database->things;

my $res = $collection->find_one( { text => qr/tkdhoncho/i } );
print encode_utf8( $res->{text} );

AmberleeAmberlee2011/10/08 04:36Mighty useful. Make no mitsake, I appreciate it.

lnqtbfklnqtbfk2011/10/08 21:368HtFYr <a href="http://fvreeqsabrni.com/">fvreeqsabrni</a>

gbtcvklhhgbtcvklhh2011/10/11 01:41yrLSIT <a href="http://epuayycfwcdx.com/">epuayycfwcdx</a>

nqsdxyfojmnqsdxyfojm2011/10/13 02:22ojGQAD , [url=http://hfodkcmpslwo.com/]hfodkcmpslwo[/url], [link=http://txvomkdscpep.com/]txvomkdscpep[/link], http://nukxlkqpmlpj.com/

トラックバック - http://perl.g.hatena.ne.jp/ishiduca/20100916

2010-09-13

[]MongoDBをはじめてみました その2 12:31 MongoDBをはじめてみました その2 - ishiducaの日記 を含むブックマーク はてなブックマーク - MongoDBをはじめてみました その2 - ishiducaの日記 MongoDBをはじめてみました その2 - ishiducaの日記 のブックマークコメント

昨日の復習でやってみた。

Twitter検索の結果をそのまま書き込むだけなんだけど。

やっているのはこんな事

  • Twitter検索APIに適当な検索語彙を投げる
  • 返ってきた結果(JSONなテキスト)をPerlのオブジェクト(ハッシュ)に変換する
  • MongoDBのオブジェクトを使って変換したハッシュを書き込む

insert.pl

$ insert.pl \#tkdhoncho

って感じで使う

#!/usr/bin/env perl
use strict;
use warnings;
use URI;
use LWP::UserAgent;
use MongoDB;
use JSON;
use Data::Dumper;

@ARGV or die qq(not found query\n);

my $uri = URI->new( 'http://search.twitter.com/search.json' );
$uri->query_form( "q" => $ARGV[0] );

my $ua = LWP::UserAgent->new;
my $response = $ua->get( $uri );
$response->is_success or die $response->status_line;

my $json = decode_json( $response->{_content} );

my $connection = MongoDB::Connection->new( host => 'localhost', port => 27017 );
my $database   = $connection->mydb;
my $collection = $database->things;

my $id   = $collection->insert($json);
my $data = $collection->find_one({ _id => $id });

print Dumper $data;

exit 0;

mongo shellで確認

> db.things.find();
{ "_id" : ObjectId("4c8d9057a74100ed03000000"), "page" : NumberLong( 1 ), "query" : "%23tkdhoncho", "completed_in" : 0.024583999999999998, "refresh_url" : "?since_id=24333258105&q=%23tkdhoncho", "results_per_page" : NumberLong( 15 ), "max_id" : NumberLong( 2.43333e+10 ), "results" : [
	{
		"source" : "&lt;a href=&quot;http://twitter.com/&quot;&gt;web&lt;/a&gt;",
		"to_user_id" : null,
		"geo" : null,
		"profile_image_url" : "http://a0.twimg.com/profile_images/428821568/876_2_normal.png",
		"from_user_id" : NumberLong( 422216 ),
		"iso_language_code" : "ja",
		"created_at" : "Sat, 11 Sep 2010 14:23:28 +0000",
		"text" : "散歩がてらに立ち寄ったというのに完全にスルーしてた #tkdhoncho:「上越のニュースサイト:上越タウンジャーナル » Blog Archive » 上越のご当地グルメ!?サメカレー新登場」 http://j.mp/b10Z70",
		"metadata" : {
			"result_type" : "recent"
		},
		"id" : NumberLong( 2.41979e+10 ),
		"from_user" : "ishiduca"
	}
], "since_id" : NumberLong( 0 ) }

書き込みは成功している。数値は NumberLong( xxx ) って書き込まれてるんですね。

GalinaGalina2013/02/02 13:52That takes us up to the next level. Great piosntg.

qitqxoraqqitqxoraq2013/02/04 13:50j4iVkd <a href="http://zgvbeoiqthbt.com/">zgvbeoiqthbt</a>

gqmgcgcyqlgqmgcgcyql2013/02/04 20:25SPLwIf , [url=http://kxfbcpbfzdqr.com/]kxfbcpbfzdqr[/url], [link=http://ogxostzwzdko.com/]ogxostzwzdko[/link], http://blrvjetftbmv.com/

トラックバック - http://perl.g.hatena.ne.jp/ishiduca/20100913

2010-09-12

[]MongoDBはじめてみました 14:46 MongoDBはじめてみました - ishiducaの日記 を含むブックマーク はてなブックマーク - MongoDBはじめてみました - ishiducaの日記 MongoDBはじめてみました - ishiducaの日記 のブックマークコメント

DataBaseはまったく取り扱ったことがなかったので、SQLである必要もないし、まあ何でもいいかという甘い認識のもと手を出してみました。MongoDBのシェルがjavascriptっていうのも僕には取っ付き易そうだったし。

んで、はじめの一歩。その記録

まず、MongoDBのダウンロードとインストール

# ホームディレクトリに置いた
$ cd $HOME

# ここから環境にあったものをさがす
# http://www.mongodb.org/downloads
# ちなみに SnowLeopard 32bit版
$ sudo curl -O http://fastdl.mongodb.org/osx/mongodb-osx-i386-1.6.2.tgz
$ sudo tar zxvf mongodb-osx-i386-1.6.2.tgz
$ sudo rm mongodb-osx-i386-1.6.2.tgz

データベースのディレクトリを作成する

# ホームディレクトリに「MongoDB」ディレクトリを作る
$ cd $HOME
$ mkdir MongoDB

フロントエンドで起動(デーモン起動はまたあとで)

$ mongodb-osx-i386-1.6.2/bin/mongd --dbpath ~/MongoDB

するとこんな感じで表示される

Sun Sep 12 12:34:12 MongoDB starting : pid=293 port=27017 dbpath=Mongodb 32-bit 

 NOTE: when using MongoDB 32 bit, you are limited to about 2 gigabytes of data
       see http://blog.mongodb.org/post/137788967/32-bit-limitations

Sun Sep 12 12:34:12 db version v1.6.2, pdfile version 4.5
Sun Sep 12 12:34:12 git version: aef371ecf5d2a824f16ccdc3b745f3702165602f
Sun Sep 12 12:34:12 sys info: Darwin broadway.local 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386 BOOST_LIB_VERSION=1_40
Sun Sep 12 12:34:12 [initandlisten] waiting for connections on port 27017
Sun Sep 12 12:34:12 [websvr] web admin interface listening on port 28017

特にエラーもでてないので、別のターミナルからMongoDBのシェルで動作確認
$ mongodb-osx-i386-1.6.2/bin/mongo
# シェルが立ち上がる
MongoDB shell version: 1.6.2
connecting to: test

# データベースは初期設定で ローカルホストの"test"データベースに接続しているので、自分のデータベースに接続先を変更する
> use mydb
switched to db mydb

# 試しに "things" というコレクションにデータを書き込みます
> var myData = { name : 'ishiduca', interest : 'perl' };
> db.things.save(myData);

# thingsコレクションに格納したデータを見る
> db.things.find();
{ "_id" : ObjectId("4c8c523d98eef5502687b26c"), "name" : "ishiduca", "interest" : "perl" }

# ここで、立ち上がっているMongoDBを停止するには「admin」モードでシャットダウンする
# > use admin
# stitched to db admin
# > db.shutdownServer()
# Sun Sep 12 13:39:33 query failed : admin.$cmd { shutdown: 1.0 } to: 127.0.0.1

# シェルを終了させる
> exit

MongDBを停止する

フロントエンドの場合は、先程のシェルコマンドを使ってもいいし、「Ctrl + c」でもいい

参照「MongoDB : Starting and Stopping Mongo

※ 上手く終了できないと、次回MongoDBは立ち上がってこないのでその場合は --repair オプションを付けて mongod する

$ mongodb-osx-i386-1.6.2/bin/mongod --dbpath=Mongodb --repair

そのあと、再起動

$ mongodb-osx-i386-1.6.2/bin/mongod --dbpath=Mongodb

perlからいじる(なんかオマケみたいだけど)

MongoDBシェルからやったのと同じように書き込みしてみるテストスクリプト

#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use MongoDB;

my $connection = MongoDB::Connection->new( host => 'localhost', port => 27017 );
my $database   = $connection->mydb;
my $collection = $database->things;

my $id   = $collection->insert({ hoge => 'MongoDB and perl and 対話型bot'});
my $data = $collection->find_one({ _id => $id });

print "$id\t$data->{hoge}\n";

exit 0;

結果

4c8c591da74100cf01000000	MongoDB and perl and 対話型bot

MongoDBシェルからも確認

$ mongodb-osx-i386-1.6.2/bin/mongo
> use mydb
> db.things.find()
{ "_id" : ObjectId("4c8c523d98eef5502687b26c"), "name" : "ishiduca", "interest" : "perl" }
{ "_id" : ObjectId("4c8c591da74100cf01000000"), "hoge" : "MongoDB and perl and 対話型bot" }

最初に書き込んだデータも残ってるし、perlスクリプトで書き込んだものも残ってる。

体調が悪いので今日はここまで。(MongoDB+perlの日本語ドキュメントあんまり見ない。MongoDB+Railsはドキュメント多いんだけどな)