春山 征吾のくけー

https://www.unixuser.org/~haruyama/blog/ に移転しました http://wiki.livedoor.jp/haruyama_seigo/d/FrontPage @haruyama タイトルが思いつかないときはそのときかかってた曲をタイトルにしています.

2012年04月

2012/05/29 に @ haruyama と飲む会を開催します

2012/05/29 に @ haruyama と飲む会を開催します.

@ haruyama と飲む会 2012/05/29

これまでに2回開催しました.

@ haruyama と飲む会 2011/11/09

集まって適当な話をするだけの会です. mixi の施設を利用するのでコストは低めでやれます.

Solr の FunctionQuery を増やしてみた.

今後, Solr においてランキングを外部から挿入したいという話が増えると考えています. たとえば, 検索した人に近い人を上位に出したいという場合です.

Solr 3.1 からは FunctionQuery - Solr Wiki がソートに利用できます. ここで, dist_between_users(id1,id2) という 2者間の距離を求める独自の FunctionQuery を追加してみました.

users となっていますが, 別にユーザ間である必要はありません.

  • ユーザid:1 と他のユーザとの距離でソートするクエリ
    • q=*:*&sort=dist_between_users(1,id) desc
  • さらにスコアとして距離を表示するクエリ
    • q=_val_:"dist_between_users(1,id)"&fl=*,score&sort=dist_between_users(1,id) desc

組込み方はこんな感じです.

solrconfig.xml に以下の記述を追加します.

  <valueSourceParser name="dist_between_users" class="org.unixuser.haruyama.solr.search.function.DistBetweenUsersParser">
  </valueSourceParser>

以下の3つのクラスで構成されています.

DistBetweenUsersParser が入力を DistBetweenUsersFloatFunction に渡します.

class DistBetweenUsersParser extends ValueSourceParser {

  // In actual environments, you would set parameters of storage.
  //override def init(args : NamedList[String]) { }

  override def parse(fp :FunctionQParser) : ValueSource = {
    val sources = fp.parseValueSourceList();

    return new DistBetweenUsersFloatFunction(sources.toArray(new Array[ValueSource](sources.size)))
  }
}

DistBetweenUsersFloatFunction が入力を処理して結果を返します.

class DistBetweenUsersFloatFunction(sources : Array[ValueSource]) extends MultiFloatFunction(sources) {

  override protected def name() : String = "dist_between_users"

  override protected def func(doc : Int, valsArr : Array[DocValues]) : Float = {

    require(valsArr.length == 2, "dist_between_users needs 2 arguments, but " + valsArr.length + " argument(s).")

    val first = valsArr(0).intVal(doc)
    val second = valsArr(1).intVal(doc)

    DistBetweenUsersStorage.get(first, second)
  }
}

DistBetweenUsersStorage は本当は外部のストレージに問合せることにになりますが, ここでは手を抜いています.

object DistBetweenUsersStorage {
  private val distMap = Map("1,2" -> 1.0f, "1,3" -> 2.0f)

  def get(first: Int, second : Int) : Float = {

    if (first == second) {
      return Float.MinValue
    }

    distMap.getOrElse("%d,%d".format(math.min(first, second), math.max(first, second)), 0.0f)
  }
}

テストはありません. テストを書くなら Java で書いて solr/core/src/test/org/apache/solr/search/function/TestFunctionQuery.java をコピペしたテストを書いたほうが楽そうです.

2012/04/13 Anuenue 0.7.5 リリース

2012/04/13 anuenue-wrapper 0.7.5 をリリースしました.

Apache Solr 3.6.0 と lucene-gosen 2.0.0 への対応を行ないました.

#LUCENE-3305 Kuromoji code donation - a new Japanese morphological analyzer - ASF JIRA と それに伴なう lucene-gosen のクラス名変更のため, lucene-gosen を利用している場合, 既存の schema.xml との互換性がありません.

会社のマシンで適当なベンチマークをした結果をTwitterに書きました.

2011/05 の計測 ( Solr/Tokenizer評価201105) ) に比べると だいぶ kuromoji の性能があがったようにみえます.

QRコード
QRコード
  • ライブドアブログ