Kouhei Sutou
kou****@clear*****
2012年 8月 24日 (金) 17:31:04 JST
須藤です。 In <CAP4YgqMMqUiijkyHdgwky_mzBjMhgg5AQ6zF4=Qu3jd****@mail*****> "[groonga-dev,01022] インデックスカラムを参照する方法を教えてください" on Fri, 24 Aug 2012 12:37:22 +0900, okk okk <mikke****@gmail*****> wrote: > rroonga で保存された "Yes good" の文章からTokenMecabでトークナイズされた > 単語 "Yes" と "good" を取得するところで悩んでいます。 > 文章は切り分けられ語彙表(lexicon)にちゃんと入っています。 > > 「groongaにデータを登録してからインデックスが更新されるまでの流れ」 > http://www.clear-code.com/blog/2011/10/5.html > ”groongaのインデックスカラムでは、…” > を参考にindex column が参照できれば、切り分けられた単語を取得できると考えたのですが、 > インデックスカラムの参照方法がわかりませんでした。 > > インデックスカラムを参照する方法はありますでしょうか。 単語に対応する元文書を参照したいということでしょうか? それとも、切り分けられた単語を参照したいということでしょ うか?(後者な雰囲気を感じますが。。。) まずは、前者から説明します。単語に対応する元文書を参照し たい場合は以下のようにTable#selectを使うのが便利です。 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"] comments.add(:content => "Yes good") Groonga::Context.default.match_escalation_threshold = -1 word = "Yes" result_set = comments.select do |record| record.content =~ word end p result_set.collect(&:attributes) # -> [{"_id"=>1, "_key"=>{"_id"=>1, "content"=>"Yes good"}, "_score"=>1, "_nsubrecs"=>1}] ポイントはGroonga::Context#match_escalation_threshold=で-1を 指定して完全一致しかさせないようにしているところです。これを しないと切り分けた単語以外でもヒットしてしまいます。 ↑の例だと「Ye」でもヒットしてしまいます。 match_escalation_thresholdについては以下のドキュメントが参考 になると思います。 http://groonga.org/ja/docs/reference/commands/select.html#match-escalation-threshold http://groonga.org/ja/docs/spec/search.html 次に後者の説明です。切り分けられた単語を参照したい場合は 語彙表をeachして語彙表の各レコードのkeyを参照してください。 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, :default_tokenizer => :token_mecab) do |table| table.index("Comments", "content") end end comments = Groonga["Comments"] comments.add(:content => "Yes good") comments.add(:content => "No good") terms = Groonga["Terms"] terms.each do |term| p term.key # -> "N" # -> "Yes" # -> "good" # -> "o" end ↑の例では「N」、「Yes」、「good」、「o」が切りだされた単語で す。 語彙表のレコードのkeyを参照するのは、そこに単語が入って いるからです。 http://www.clear-code.com/blog/2011/10/5.html の http://www.clear-code.com/blog/images/20111005_9.png でもlexiconのkeyに"Hey"や"Hi"などが入っていますよね。 > 試行結果 > irb(main):004:0> terms = Groonga["Terms"] > => #<Groonga::PatriciaTrie id: <276>, name: <Terms>, path: > </tmp/tmpdb/test3.db.0000114>, domain: <ShortText>, range: (nil), flags: > <KEY_NORMALIZE|WITH_SECTION>, encoding: <:utf8>, size: <79417>> > irb(main):005:0> terms.columns[0] > => #<Groonga::IndexColumn id: <277>, name: <Terms.Comments_comment>, path: > </tmp/tmpdb/test3.db.0000115>, domain: <Terms>, range: <Comments>, flags: > <>> > irb(main):011:0> terms.columns[0][1] > => 111 > > 転置インデックスのArrayが返ってくることを期待していましたが数値が返ってきました。 > 111 のID?の意味もよく理解していません。 実は、この111はIDではなく、指定した単語IDに関連付いてい る文書数はいくつくらいあるかの概算値なのです。もう少し詳しく 説明します。 > irb(main):011:0> terms.columns[0][1] の terms.columns はTermsテーブル内の全カラムを配列で返します。 terms.columns[0] は最初のカラムという意味です。 terms.columns[0][1] は最初のカラムの単語IDが1の単語に関連付けられれている文書数が いくつくらいあるかの概算値という意味です。 例としてこの状態を考えます。 comments = Groonga["Comments"] comments.add(:content => "Yes good") terms = Groonga["Terms"] terms = Groonga["Terms"] terms.each do |record| p [record.id, record.key] # -> [1, "Yes"] # -> [2, "good"] end このとき、単語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)に関連付けられれている文書数の概算値 という感じなのですが、そもそも、質問をうまく受け取れていない 気もするので、お役に立てていない感があります。。。 -- 須藤 功平 <kou****@clear*****> 株式会社クリアコード <http://www.clear-code.com/> (03-6231-7270) groongaサポート: http://groonga.org/ja/support/ パッチ採用はじめました: http://www.clear-code.com/recruitment/