これはGroonga Advent Calendar 2016の17日目の記事です。2/3まで来ましたね! 昨日は @groonga さんのGroongaでの複数カラムとインデックスと--match_columnsパラメータの複雑な関係でした。
groonga-dev(OSDNのML)を全文検索する(クロール編) - Qiitaの続きです。今回はクロールしたMLアーカイブからインデックスを作ります。
インデックスを作成するスクリプトはこちらです。Groongaのデータベースを作って、データを入れて、全文検索用のインデックスを作るところまでやっています。
# -*- coding: utf-8 -*-
require "grn_mini"
require "fileutils"
require "mail"
require "./config"
FileUtils.mkdir_p(DB_DIR)
db_path = File.join(DB_DIR, "groonga-dev-search.db")
GrnMini.create_or_open(db_path)
hash = GrnMini::Hash.new
Dir.glob("#{DATA_DIR}/*") do |path|
index_by_month = 0
basename = File.basename(path, ".txt")
File.open(path, "r:utf-8") do |file|
text = ""
file.each_line do |line|
case line
when /^From /
next if text.empty?
mail = Mail.new(text)
text = ""
index_by_month += 1
key = "#{basename}-#{"%04d" % index_by_month}"
hash[key] = {
:from => mail.from,
:date => mail.date.to_s,
:subject => mail.subject,
:body => mail.body.to_s.encode("UTF-8", mail.charset),
}
else
text << line
end
end
end
end
短いですね。grn_mini1を使っているので、スキーマの定義を省略できているのが大きいです。細かい設定をするには自前でスキーマ定義を書いたほうがよいですが、サンプルスクリプトのように細かい設定が不要の用途で使うにはもってこいのgemです。
メールのパースにはRubyのmail gemを使っています。クロールしたMLアーカイブは複数のメールが含まれているので、パースする前に区切ってやる必要があります。From
から始まる行が1通のメールの先頭行になっているので、その行が来たらそれまでの行をパースしてDBに入れるという流れで処理を行っています。
次回予告
groonga-devを全文検索する一環として、クロールしたMLアーカイブからインデックスを作成する方法を紹介しました。
次回はいよいよgroonga-devを全文検索する方法について書きたいと思います。
明日は @KitaitiMakoto さんのRailsでの検索機能にgroonga-client-railsを使う(前編)です!