2016-05-10 10 views
0

ich damit ein einfaches Spiel Suche tatsächlich durchführen kann:Elasticsearch Spiel mehrere Felder mit unterschiedlichen Werten

query: {match: {searchable: {query:search}}} 

Das funktioniert gut, ist mein durchsuchbare Feld in meinem Mapping analysiert.

Jetzt möchte ich eine Suche für mehrere Felder durchführen: 1 String, und alle anderen sind numerisch.

Mein Mapping:

mappings dynamic: 'false' do 
     indexes :searchable, analyzer: "custom_index_analyzer", search_analyzer: "custom_search_analyzer" 
     indexes :year, type: "integer" 
     indexes :country_id, type: "integer" 
     indexes :region_id, type: "integer" 
     indexes :appellation_id, type: "integer" 
     indexes :category_id, type: "integer" 
     end 

def as_indexed_json(options={}) 
     as_json(
     only: [:searchable, :year, :country_id, :region_id, :appellation_id, :category_id] 
    ) 
    end 

Ich habe versucht, dies:

query: { 
        filtered: { 
         query: { 
         match: { 
          searchable: search 
         } 
         }, 
         filter: { 
         term: { 
          country_id: "1" 
         }, 
         term: { 
          region_id: "2" 
         }, 
         term: { 
          appellation_id: "34" 
         } 
         } 
        } 
        }, 
        sort: { 
        _score: { 
         order: :desc 
        }, 
        year: { 
         order: :desc, 
         ignore_unmapped: true 
        } 
        }, 
        size:100 

Es funktioniert gut, aber es wird mir 100 Ergebnisse in allen Fällen geben, von der appellation_id (34) gesendet, auch wenn Das durchsuchbare Feld ist sehr weit von der Textsuche entfernt.

Ich habe auch versucht, eine BOOL Abfrage:

self.search(query: { 
       bool: { 
        must: [ 
        { 
         match: { 
          country_id: "1" 
          }, 
          match: { 
          region_id: "2" 
          }, 
          match: { 
          appellation_id: "34" 
          }, 
          match: { 
          searchable: search 
          } 
        } 
        ] 
       } 
       }, 
       sort: { 
       _score: { 
        order: :desc 
       }, 
       year: { 
        order: :desc, 
        ignore_unmapped: true 
       } 
       }, 
       size:100 
      ) 

aber es wird alle Ergebnisse geben mir die durchsuchbare Feld passend und kümmern sich nicht um die appellation_id wollte.

Mein Ziel ist es, die besten Ergebnisse und Leistung zu erzielen und ES bitten, mir alle Daten von country_id = X, region_id = Y, appellation_id = Z und schließlich eine Übereinstimmung mit dieser Reihe von Ergebnissen mit dem durchsuchbaren Feld durchzuführen. und erzielen mit dem durchsuchbaren Text keine weit entfernten Ergebnisse.

Danke.

Antwort

0

Wie Sie vielleicht wissen elasticsearch match Abfrage gibt das Ergebnis basierend auf einem relevance score zurück. Sie können versuchen, Abfrage anstelle von Übereinstimmung für eine exakte Ausdrucksmatch zu verwenden. Auch ich denke, dass Ihre Bool-Abfrage-Struktur wie folgt sein muss:

bool: { 
     must: [ 
      { match: { 
       country_id: "1" 
       }}, 
      {match: { 
      region_id: "2" 
      }}, 
      {match: { 
      appellation_id: "34" 
      }}, 
      {match: { 
      searchable: search 
      }} 
     ] 
    } 
+0

Alpert, Es funktioniert gut mit Ihrer neuen Struktur (double {} um Spiel). Ich habe auch mit ** Begriff ** anstatt ** Übereinstimmung ** versucht und die gleichen Werte erhalten. So danke. Mein einziges Problem ist das durchsuchbare Feld (das Mapping verwendet ngrams): Wie kann man Ergebnisse stoppen, wenn die gefundenen Begriffe nicht das sind, was erwartet wird? Zum Beispiel wird die Suche nach "beaulieu" 2 schöne Ergebnisse und 98 sehr sehr weit von diesem Wort geben. Scoring sprang von 11 auf 2 ... aber es hängt von den gesuchten Begriffen ab. –

+0

Ich kann den Parameter min_score verwenden, aber es ist ein willkürliches Muster. –

+0

Überprüfen Sie, ob minimum_should_match für Sie funktioniert: https://www.elastic.co/guide/en/elasticsearch/guide/current/grams-compound-words.html – alpert