Kouhei Sutou
kou****@clear*****
2012年 6月 8日 (金) 09:21:17 JST
須藤です。 In <20120****@gmail*****> "[groonga-dev,00933] Re: rroonga での scoreの設定方法" on Wed, 06 Jun 2012 17:59:41 +0900, Shinya Kawaji <kawaj****@gmail*****> wrote: > 以前のメールで、 > >> result_set = Groonga["Site"].select >> # ↑が--filter "1"相当 >> result_set.select("_score = rand() && false", :syntax => :script) >> # ↑が--scorer "_score = rand()"相当 >> result_set.sort(["_score"]) >> # ↑が--sortby "_score"相当 > > で、rroongaの場合でのスコアの設定方法を知ることが出来ました。 > > > 実際に使っているのは ActiveGroongaなのですが、 > > class ActiveGroonga::ResultSet > def sort_by_shuffle(opts = {}) > create_result_set( > @records.select("_score = rand()", :syntax => :script).sort( > ["_score"], opts > ) > ) > end > end > > のように仕込んで、 > > Site.all.sort_by_shuffle(:limit => 5) > > などとしています。 あ、これはですね、↓のようにするのが正しいです。 class ActiveGroonga::ResultSet def sort_by_shuffle(opts = {}) @records.select("_score = rand() && false", :syntax => :script) sort(["_score"], opts) end end 元の書き方だとrand()の結果が0になったレコードが消えてしまい ます。(ほとんどないと思いますが。。。) > この場合、示してくださった "_score = rand() && false" では正しく取得出来 > ず、"_score = rand()" だけを指定しているのですが、以下の引用にある > 「呼んでいて結果は使いません」という状態になっていないのではないかと > 危惧しています。 はい、なっていません。 元の書き方ではselect("_score = rand()")の結果を使っています が、ここに結果が入ること自体が「余分な結果」になります。 新しい書き方のようにselectの結果は空(1件もレコードがヒット しない状態)にする必要があります。 "_score = rand()"の部分で@recordsそれ自体の_scoreカラムの値 が書き換わっているため、sortするのはselectの結果ではなく @recordsそのものを使います。 > この場合、処理のたびに余分な結果をメモリに積むことになってしまうのでは > ないかと思い、パフォーマンスに影響が出るのではないかと危惧していますが、 > いかがでしょうか。 @recordsの件数が少ないとあまりきにならないかもしれませんが、 大きいと影響がわかりやすくなってくるかもしれません。@records と同じ分のレコードを持ったテーブル(= selectの結果)を新しく 作るためのリソース(CPUとメモリ)が増えると思います。 (selectの結果を解放するときのリソースも少し増えるかも。) -- 須藤 功平 <kou****@clear*****> 株式会社クリアコード <http://www.clear-code.com/> (03-6231-7270) groongaサポート: http://groonga.org/ja/support/ プログラミングが好きなソフトウェア開発者を募集中: http://www.clear-code.com/recruitment/