2

私は現在、タイヤの宝石を見つけ出し(elasticsearchとluceneも初めてです)、いくつか試しています。私はいくつかの(おそらく重要な)スコアリングを行う必要があるので、それを把握しようとします. スコアリング式についてウェブ上で見つけたものをすべて読み、見つけたものを説明されたクエリと照合しようとしています.

数字を正しく読むと、「foo foo foo foo」というタイトルのドキュメントのスコアが異なりますが、これは確かに意図したものではありません。インデックス作成中またはインデックス作成後にステップが欠落していると思いますが、わかりませんでした。

以下は私のコードです。私はタイヤ DSL が意図した通りには進んでいません。なぜなら、私は物事を理解したいからです。

require 'tire'
require 'pp'

class Model
  INDEX = 'myindex'
  TYPE = 'company'

  class << self
    def delete_index
      Tire.index(INDEX) { delete }
    end

    def create_mapping
      Tire.index INDEX do
        create mappings: {
          TYPE => {
            properties: {
              title: { type: 'string' }
            }
          }
        }
      end
    end

    def refresh_index
      Tire.index INDEX do
        refresh
      end
    end
  end

  def initialize(attributes = {})
    @attributes = attributes.merge(:_id => object_id) #use oid as id, just for testing
  end

  def _type
    TYPE
  end

  def id
    object_id.to_s #convert to string because tire compares to object_id!
  end

  def index
    item = self
    Tire.index INDEX do
      store item
    end
  end

  def to_indexed_json
    @attributes.to_json
  end

  ENTITIES = [
    new(title: "foo foo foo foo"),
    new(title: "foo"),
    new(title: "bar"),
    new(title: "foo bar"),
    new(title: "xxx"),
    new(title: "foo foo foo foo"),
    new(title: "foo foo"),
    new(title: "foo bar baz")
  ]

  QUERIES = {
    :foo => { query_string: { query: "foo" } },
    :all => { match_all: {} }
  }

  def self.custom_explained_search(q)
    Tire.search(Model::INDEX, :wrapper => Model, :explain => true) do |search|
      search.query do |query|
        query.send :instance_variable_set, :@value, q
      end
    end
  end
end

class Tire::Results::Collection
  def explained
    @response["hits"]["hits"].map do |hit|
      {
        "_id" => hit["_id"],
        "_explanation" => hit["_explanation"],
        "title" => hit["_source"]["title"]
      }
    end
  end
end

Model.delete_index
Model.create_mapping
Model::ENTITIES.each &:index
Model.refresh_index
s = Model.custom_explained_search(Model::QUERIES[:foo])
pp s.results.explained

印刷結果は次のとおりです。

[{"_id"=>"2169251840",
  "_explanation"=>
   {"value"=>0.54932046,
    "description"=>"fieldWeight(_all:foo in 0), product of:",
    "details"=>
     [{"value"=>1.4142135,
       "description"=>"btq, product of:",
       "details"=>
        [{"value"=>1.4142135, "description"=>"tf(phraseFreq=2.0)"},
         {"value"=>1.0, "description"=>"allPayload(...)"}]},
      {"value"=>0.7768564, "description"=>"idf(_all:  foo=4)"},
      {"value"=>0.5, "description"=>"fieldNorm(field=_all, doc=0)"}]},
  "title"=>"foo foo foo foo"},
 {"_id"=>"2169251720",
  "_explanation"=>
   {"value"=>0.54932046,
    "description"=>"fieldWeight(_all:foo in 1), product of:",
    "details"=>
     [{"value"=>0.70710677,
       "description"=>"btq, product of:",
       "details"=>
        [{"value"=>0.70710677, "description"=>"tf(phraseFreq=0.5)"},
         {"value"=>1.0, "description"=>"allPayload(...)"}]},
      {"value"=>0.7768564, "description"=>"idf(_all:  foo=4)"},
      {"value"=>1.0, "description"=>"fieldNorm(field=_all, doc=1)"}]},
  "title"=>"foo"},
 {"_id"=>"2169250520",
  "_explanation"=>
   {"value"=>0.48553526,
    "description"=>"fieldWeight(_all:foo in 2), product of:",
    "details"=>
     [{"value"=>1.0,
       "description"=>"btq, product of:",
       "details"=>
        [{"value"=>1.0, "description"=>"tf(phraseFreq=1.0)"},
         {"value"=>1.0, "description"=>"allPayload(...)"}]},
      {"value"=>0.7768564, "description"=>"idf(_all:  foo=4)"},
      {"value"=>0.625, "description"=>"fieldNorm(field=_all, doc=2)"}]},
  "title"=>"foo foo"},
 {"_id"=>"2169251320",
  "_explanation"=>
   {"value"=>0.44194174,
    "description"=>"fieldWeight(_all:foo in 1), product of:",
    "details"=>
     [{"value"=>0.70710677,
       "description"=>"btq, product of:",
       "details"=>
        [{"value"=>0.70710677, "description"=>"tf(phraseFreq=0.5)"},
         {"value"=>1.0, "description"=>"allPayload(...)"}]},
      {"value"=>1.0, "description"=>"idf(_all:  foo=1)"},
      {"value"=>0.625, "description"=>"fieldNorm(field=_all, doc=1)"}]},
  "title"=>"foo bar"},
 {"_id"=>"2169250380",
  "_explanation"=>
   {"value"=>0.27466023,
    "description"=>"fieldWeight(_all:foo in 3), product of:",
    "details"=>
     [{"value"=>0.70710677,
       "description"=>"btq, product of:",
       "details"=>
        [{"value"=>0.70710677, "description"=>"tf(phraseFreq=0.5)"},
         {"value"=>1.0, "description"=>"allPayload(...)"}]},
      {"value"=>0.7768564, "description"=>"idf(_all:  foo=4)"},
      {"value"=>0.5, "description"=>"fieldNorm(field=_all, doc=3)"}]},
  "title"=>"foo bar baz"},
 {"_id"=>"2169250660",
  "_explanation"=>
   {"value"=>0.2169777,
    "description"=>"fieldWeight(_all:foo in 0), product of:",
    "details"=>
     [{"value"=>1.4142135,
       "description"=>"btq, product of:",
       "details"=>
        [{"value"=>1.4142135, "description"=>"tf(phraseFreq=2.0)"},
         {"value"=>1.0, "description"=>"allPayload(...)"}]},
      {"value"=>0.30685282, "description"=>"idf(_all:  foo=1)"},
      {"value"=>0.5, "description"=>"fieldNorm(field=_all, doc=0)"}]},
  "title"=>"foo foo foo foo"}]

数字の読み方が間違っていますか?それともタイヤを悪用?たぶん、「コレクション全体の再インデックス」ステップが欠落しているだけですか?

4

1 に答える 1

2

afaik明示的な並べ替えフィールドが定義されていない場合、並べ替えのデフォルトは(の変形)tf * idf(http://en.wikipedia.org/wiki/Tf * idf)です。

文字通り:用語頻度*逆ドキュメント頻度。

ウィキペディアから:

用語頻度(用語カウント):特定のドキュメントの用語カウントは、単に特定の用語がそのドキュメントに表示される回数です。

逆ドキュメント頻度は、その用語がすべてのドキュメントで共通であるかまれであるかを示す尺度です。これは、ドキュメントの総数を用語を含むドキュメントの数で割り、その商の対数をとることによって得られます。

この場合、並べ替えの「用語頻度」コンポーネントにより、「foo」を検索すると、「foofoofoofoo」のスコアが他のドキュメントよりも高くなる可能性があります。

さらに、IDを変更したときに表示される効果について:わかりませんが、ESがid内部的にの順序でドキュメントを保存する必要があると思います(それについてはわかりません)...

その場合、同じソートスコアを持つ2つのドキュメントは、タイブレーカーとしてIDに基づいてソートされます。もちろん、この動作を変更するために複数の並べ替えを定義できます(例:sort = sorta + desc、sortb + desc。この場合、sortbはscoreAで同じスコアのすべてのドキュメントのタイブレーカーとして使用されます)

于 2012-07-09T18:40:06.623 に答える