[groonga-dev,00950] Re: rroonga での scoreの設定方法

Back to archive index

Kouhei Sutou kou****@clear*****
2012年 6月 11日 (月) 16:25:53 JST


須藤です。

In <20120****@gmail*****>
  "[groonga-dev,00949] Re: rroonga での scoreの設定方法" on Mon, 11 Jun 2012 15:56:04 +0900,
  Shinya Kawaji <kawaj****@gmail*****> wrote:

>> あ、これはですね、↓のようにするのが正しいです。
>> 
>>   class ActiveGroonga::ResultSet
>>     def sort_by_shuffle(opts = {})
>>       @records.select("_score = rand() && false", :syntax => :script)
>>       sort(["_score"], opts)
>>     end
>>   end
> 
> 詳しく教えてくださり、ありがとうございます。
> 
> ただちょっと、上の書き方では以下の点が上手くいかないように思うのですが、
> 一般的にも再現する話でしょうか。

すみません。。。

>>       @records.select("_score = rand() && false", :syntax => :script)

の

  _score = rand() && false

の部分は

  (_score = rand()) && false

としなければいけませんでした。。。

(...)をつけないと

  _score = (rand() && false)

というように解釈され_scoreがかならず0(= falseを数値にキャス
トした値)になってしまいます。

なので、

> ■繰り返し行ってもランダムな値を返さない

となっていました。

>  ■Item.all.sort_by_shuffle と続けられない
...
> all と select の両メソッドは、「絞り込みをするかしないか」くらいの違いし
> か無いという認識だったのですが、なぜか all のほうは動作しませんでした。

実はもっと違いがあるのです。
selectの方は検索結果を格納するために一時的なテーブルを作成し
てそこにヒットしたレコード(のID)を入れるのですが、allの方
はテーブルにあるすべてのレコードがヒットすることがすでにわかっ
ているため、一時的なテーブルを作らないのです。

_scoreの格納場所は一時的なテーブルになるため、
sort_by_shuffleのケースではallではなくselectを使って一時的な
テーブルを作成する必要があります。

[groonga-dev,00842]の↓が関連情報になります。
http://sourceforge.jp/projects/groonga/lists/archive/dev/2012-May/000842.html

> groongaでは検索処理の結果を一時テーブル(*)に格納します。実
> は、_scoreカラムがあるのはSiteなどの永続的なテーブルではなく
> 一時テーブルにあります。これは、永続的なテーブルに_scoreを追
> 加すると同時に複数の検索結果に_scoreをつけられないからです。
> 引数もブロックもないselectはこの一時テーブルを作っています。
> 何も条件を指定していないのですべてのレコードが格納されていま
> す。
>
> (*) 一時テーブルとはSiteなど名前がついていない、データベース
>     を閉じるとなくなってしまうテーブルのことです。

-- 
須藤 功平 <kou****@clear*****>
株式会社クリアコード <http://www.clear-code.com/> (03-6231-7270)

groongaサポート:
  http://groonga.org/ja/support/
プログラミングが好きなソフトウェア開発者を募集中:
  http://www.clear-code.com/recruitment/




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