Hatena::Groupgive-me-money

fuba needs money

楽してお金をもらえる情報募集中、@fubaとかでご連絡ください。

 | 

2012-09-09

ElasticSearch でいろんなデータに自由に全文検索インデックスを張る 00:24 ElasticSearch でいろんなデータに自由に全文検索インデックスを張る - fuba needs money を含むブックマーク はてなブックマーク - ElasticSearch でいろんなデータに自由に全文検索インデックスを張る - fuba needs money

追記:このエントリでは古い ElasticSearch モジュールを使っています。新しい公式クライアントを使ったほうがいいよ!!!

最近流行ってる ElasticSearch という Lucene ベースの便利な全文検索エンジンがあるんだけど、オレオレ画像検索をこれに移行させようとしたら Tokenizer とか Analyser とか意味わかんなくてめんどくさかったので備忘録としてエントリ書いておく。

インデックス作る奴

perl だけど、まあ create_index に json 送るだけですよ。

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

use ElasticSearch;

my $es = ElasticSearch->new(
    trace_calls => '/tmp/es_log', # デフォルトだと実行したディレクトリがログまみれになる
);

$es->delete_index(
    index => 'pics',
); # 細かくインデックスを追加することもできるみたいだけど、めんどいのでこのスクリプトはインデックス全部消して1からつくります

my $result = $es->create_index(
    index   => 'pics',
    settings => {
#        number_of_shards      => , # 一人で使うのでこのへんは無視
#        number_of_replicas    => 2,
        analysis => {
            tokenizer => {
                ngram => {
                    type => 'nGram',
                    min_gram => 2,
                    max_gram => 3
                },
            },
            analyzer => {
                default => {
                    type => 'custom',
                    tokenizer => 'ngram',
                },
                simple => {
                    type => 'simple'
                },
                tags => {
                    type => 'pattern',
                    pattern => '[\\,\\s]',
                },
            }
        }
    },
    mappings => {
        picture  => {
            properties  => {
                texts => { type => 'string', analyzer => 'default' },
                tags => { type => 'string', analyzer => 'tags' },
                time => { type => 'long', analyzer => 'simple' },
                sha256 => { type => 'string', analyzer => 'simple' },
                md5 => { type => 'string', analyzer => 'simple' },
            }
        }
    }
);

とりあえずインデックスする対象のフィールドごとに mappings に properties(それぞれのフィールドがどういう型でどの analyzer で語を分割するかとか)をどんどん書いていく。ここでは analyzer のところには同じトークナイズをしたいものは同じ名前になるように適当なものを書いていく。今回はタグがカンマ区切りのソースなので、ここだけ特殊なものにして、textsは内容なので default 、それ以外はハッシュとか数値なので simple というかんじにした。long のソートLucene よくしらんけどまあインデックス使ってくれるんでしょう。

つぎは properties で設定した名前に対応する analyzer というのを書く。default のテキストはまあ日本語だし NGram Tokenizer でいいんだけど、NGram Tokenizer の最小文字数が1文字というふざけたデフォルトなので、tokenizer の設定は細かく行いたい。そこで type: custom にして、tokenizer は名前かぶってややこしいけど ngram にした。この詳細設定はあとでやる。simple については type: simple で適当に空白とかで区切ってくれるらしいし、今回のハッシュとかには空白入ってないのでこれで文字列の完全マッチと同じになる。tags についても simple でいいんじゃね?と思ったんだけど、マニュアルみるとbut does a terrible job for some Asian languages*とか書いててびびるので type: pattern で正規表現で区切り文字を指定する。これでタグに完全マッチしてくれる。

最後にあとでやると書いといた tokenizer の細かい設定を行う。ngram という名前の tokenizer の type を nGram、2-gram から 3-gram を使うという設定にする。1文字の検索ができなくなるけど、まあ今回の実装では実は tags と texts に同じ文字列が入っているので、そういうのは tags を検索すればよい。

これで ElasticSearch で思い通りに日本語が検索ができるようになって、よかったねという話でした。

JuliaJulia 2012/09/21 13:23 I litleraly jumped out of my chair and danced after reading this!

pboqjkkadpboqjkkad 2012/09/22 00:15 4VUQxw <a href="http://xvlvqppuefba.com/">xvlvqppuefba</a>

avqshkgavqshkg 2012/09/22 12:03 lu8tCR , [url=http://ynqgyjriupkj.com/]ynqgyjriupkj[/url], [link=http://qmxdjgvgchdj.com/]qmxdjgvgchdj[/link], http://rmplgamirwhc.com/

guiadglelplguiadglelpl 2012/09/23 05:41 xIfcYZ <a href="http://xbcllstiseyg.com/">xbcllstiseyg</a>

aednjoshaednjosh 2012/09/24 20:56 AGtPDR , [url=http://axvsbydtfcag.com/]axvsbydtfcag[/url], [link=http://houqjbwwnwsj.com/]houqjbwwnwsj[/link], http://wjuorbnxxdcy.com/

ゲスト



トラックバック - http://give-me-money.g.hatena.ne.jp/fuba/20120909
 |