[groonga-dev,01024] Re: インデックスカラムを参照する方法を教えてください

Back to archive index

okk okk mikke****@gmail*****
2012年 8月 27日 (月) 04:04:16 JST


須藤様

こんにちは、temita です。
ご返信ありがとうございます。


単語に対応する元文書を参照したいということでしょうか?
> それとも、切り分けられた単語を参照したいということでしょ
> うか?(後者な雰囲気を感じますが。。。)


元文書から切り分けられた単語を参照したい。
というのがやりたかった事でした。
前回の例が非常に参考になり、目的の結果を得ることができました。
ありがとうございます。

使い道として、キーワードから文書を検索し、その文書から単語を
抜き出してさらに検索する。という流れを考えていました。

結果を載せておきます。
まずはごり押しで"Yes good"の文書から "Yes" と "good"を取りだす。

require 'rubygems'

require "fileutils"
require "groonga"

FileUtils.rm_rf("/tmp/db")
FileUtils.mkdir_p("/tmp/db")

Groonga::Database.create(:path => "/tmp/db/db")

Groonga::Schema.define do |schema|
        schema.create_table("Comments") do |table|
                table.short_text("content")
        end

        schema.create_table("Terms",
                      :type => :patricia_trie,
                      :key_type => :short_text,
                      :key_normalize => true,
                      :default_tokenizer => :token_mecab) do |table|
                              table.index("Comments", "content")
                      end
end

comments = Groonga["Comments"]
terms = Groonga["Terms"]


comments.add(:content => "Yes good")
comments.add(:content => "Not bad")

Groonga::Context.default.match_escalation_threshold = -1
comment = comments.first #最初の文書"Yes  good"を取りだす
arr = []
result_set = nil

#見つかった単語を保存していく
terms.each do |term|

        result_set = comments.select do |record|
                record.content =~ term.key
        end.select do |record|
                comment.id == record.id
        end #一度にクエリを書くやり方が分からなかった。

        arr << term if result_set.size > 0
end


p arr.collect(&:attributes)
#[{"_key"=>"good", "_id"=>2}, {"_key"=>"yes", "_id"=>1}]
#目的の"Yes" と "good"

正直、これなら mecab を毎回実行したほうが速い気が。。
なので自前で辞書を作るやり方に変更しました。

require 'rubygems'

require "fileutils"
require "groonga"

FileUtils.rm_rf("/tmp/db")
FileUtils.mkdir_p("/tmp/db")

Groonga::Database.create(:path => "/tmp/db/db")

Groonga::Schema.define do |schema|
        schema.create_table("Comments") do |table|
                table.short_text("content")
        end

        schema.create_table("Terms",
                      :type => :patricia_trie,
                      :key_type => :short_text,
                      :key_normalize => true,
                      :default_tokenizer => :token_mecab) do |table|
                              table.index("Comments", "content")
                              table.column("inverted_indexes",
:unsigned_integer16 ,:type => :vector)

                      end


end

comments = Groonga["Comments"]
terms = Groonga["Terms"]


comments.add(:content => "Yes good")
comments.add(:content => "Not bad")

Groonga::Context.default.match_escalation_threshold = -1

terms.each do |term|


        result_set = comments.select do |record|
                record.content =~ term.key
        end

        ids = result_set.collect(&:_id)
        terms.add( term.key  , :inverted_indexes => ids) #terms
にCommentsのidを保存

end

p terms.collect(&:attributes)
#[{"inverted_indexes"=>[2], "_key"=>"bad", "_id"=>4},
{"inverted_indexes"=>[1], "_key"=>"good", "_id"=>2},
{"inverted_indexes"=>[2], "_key"=>"not", "_id"=>3},
{"inverted_indexes"=>[1], "_key"=>"yes", "_id"=>1}]
各単語に対してCommentsのidをinverted_indexesにベクター型で格納しています。

#ベクターで検索出来るはずがでしたが上手くいってません。。
result = terms.select do |record|
        record.inverted_indexes == 1 #失敗。ベクター検索はできない?
end
p result.collect(&:attirbutes)
#[]

そもそも、カラムを自前で用意しなくても頑張れば元文章を参照できる気がしています。
試行結果は以上です。


このとき、単語IDが1の単語は"Yes"
>>
>> で単語IDが2の単語は"good"で
>> す。よって、以下のような意味になります。
>>
>>   index = terms.column("Comments_content")
>>   p index[1] # <- "Yes"("Yes"の単語IDは1)に関連付けられれている文書数の概算値
>>   p index[2] # <- "Yes"("good"の単語IDは2)に関連付けられれている文書数の概算値
>>
>
文章数の概算値が入っていたのですね、勉強になりました。ありがとうございました。
また、疑問が出てきた際にはどうかよろしくお願いします。m(_ _)m

---
temita <mikke****@gmail*****>
Greased Lightbox <http://shiftingpixel.com/lightbox/>
→←+-↻

Loading image

Click anywhere to cancel

Image unavailable



groonga-dev メーリングリストの案内
Back to archive index