3 Stimmen

Elasticsearch mit Tire: edgeNgram mit mehreren Wörtern

Angenommen, ich habe 5 Film-Titel:

  • Sans Soleil
  • Sansa
  • So Is This
  • Sol Goode
  • Sole Survivor

Ich möchte ein Auto-Vervollständigungssuchfeld mit folgendem erwarteten Verhalten implementieren:

  • "Sans" > Sans Soleil, Sansa
  • "Sans so" > Sans Soleil
  • "So" > So Is This, Sol Goode, Sole Survivor
  • "So Is" > So Is This
  • "Sol" > Sol Goode, Sole Survivor, Sans Soleil

Dieser Anwendungsfall scheint offensichtlich zu sein und muss von vielen angewendet werden, aber ich kann ihn einfach nicht richtig zum Laufen bringen und finde keine Antwort oder Dokumentation, die hilft. Dies ist mein aktuelles Modell:

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

Und wie die Abfrage in meinem search_controller behandelt wird:

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

Dies führt zu einem merkwürdigen Verhalten:

  • "Sans so" gibt "Sansa, Sans Soleil, So Is This" in dieser Reihenfolge zurück.
  • "So is" gibt "Sol Goode, Sans Soleil, Sole Survivor, So Is This" in dieser Reihenfolge zurück.

4voto

karmi Punkte 13269

Ich denke, du könntest das, was du möchtest, mit der match Abfrage erreichen, die auf type:"phrase_prefix" gesetzt ist. Die meisten, aber nicht alle Beispiele würden funktionieren.

Mit Ngrams hast du viel feinere Kontrolle über den Prozess, aber sie haben eine ziemlich große Recall-Rate (sie geben normalerweise mehr Daten zurück, als du möchtest), und du musst dagegen ankämpfen. Das ist das "seltsame Verhalten", das du bei mehreren Abfragesuchbegriffen ("Sans so") beobachtest, weil sie effektiv als eine Sans OR so Abfrage ausgeführt werden.

Versuche die Option default_operator: "AND" zu verwenden (siehe Tires query_string_test.rb), oder besser die match Abfrage (siehe Tires match_query_test.rb) mit der Option operator: "AND".

Es gibt einige Artikel über Autocomplete, Tire und Ngrams verfügbar:

0voto

Salil Punkte 44916

Probieren Sie Folgendes:

search = Tire.search ['Bücher', 'Filme', '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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X