3

私が5つの映画のタイトルを持っているとしましょう:

  • サンソレイユ
  • さんさ
  • これはそうですか
  • ソル・グッド
  • 唯一の生存者

この予想される動作でオートコンプリート検索フィールドを実装したいと思います。

  • "サンズ" > サンソレイユ、サンサ
  • "Sans so" > Sans Soleil
  • 「そう」>これもそうだ、ソル・グード、唯一の生存者
  • 「そうです」 > これもそうです
  • "Sol" > Sol Goode、Sole Survivor、Sans Soleil

このユースケースは明らかであり、多くの人が利用しているに違いありませんが、適切に機能させることができず、役立つ回答やドキュメントが見つからないようです. これは私の現在のモデルです:

class Film < Media
  include Tire::Model::Search
  include Tire::Model::Callbacks

  settings  :analysis => {
              :filter => {
                :title_ngram  => {
                  "type"      => "edgeNGram",
                  "min_gram"  => 2,
                  "max_gram"  => 8,
                  "side"      => "front" }
              },
              :analyzer => {
                :title_analyzer => {
                  "tokenizer"    => "lowercase",
                  "filter"       => ["title_ngram"],
                  "type"         => "custom" }
              }
            } do
    mapping do
      indexes :title, :type => 'string', :analyzer => 'title_analyzer'
      indexes :int_english_title, :type => 'string', :analyzer => 'title_analyzer'
    end
  end
end

そして、私のsearch_controllerでクエリがどのように処理されるか:

search = Tire.search ['books', 'films', 'shows'], :load => true, :page => 1, :per_page => 10 do |s|
    s.query do |query|
        query.string "title:#{params[:search]}"
    end
end
@results = search.results

これにより、いくつかの奇妙な動作が発生します。

  • "Sans so" は、"Sansa, Sans Soleil, So Is This" をこの順序で返します。
  • "So is" は、"Sol Goode, Sans Soleil, Sole Survivor, So Is This" をこの順序で返します。
4

2 に答える 2

4

matchクエリを に設定すると、目的を達成できると思いますtype:"phrase_prefix"。すべてではありませんが、ほとんどの例が機能します。

Ngrams を使用すると、プロセスをより細かく制御できますが、リコールがかなり大きくなり (通常、必要以上のデータが返されます)、それと戦わなければなりません。これは、クエリとして効果的に実行されるため、複数のクエリ用語 (「Sans so」) で観察される「奇妙な動作」ですSans OR so

default_operator: "AND"オプション (Tire のquery_string_test.rbを参照) を使用するか、matchクエリ (Tire のmatch_query_test.rbを参照) をオプションと共に使用してみてくださいoperator: "AND"

オートコンプリート、Tire、Ngrams に関する記事がいくつかあります。

于 2013-01-03T08:44:58.933 に答える
0

フォローしてみてください

search = Tire.search ['books', 'films', 'shows'], :load => true, :page => 1, :per_page => 10 do |s|
      s.query do |q|
        q.boolean do |b|
          b.must {|m| m.string params[:search]} 
        end
      end
end
于 2013-01-02T10:16:24.880 に答える