2014-01-16 10 views
6

In meinem Elasticsearch Index habe ich Dokumente, die mehrere Token an der gleichen Position haben.Elasticsearch: passen Sie jede Position nur einmal an

Ich möchte ein Dokument zurückbekommen, wenn ich mindestens ein Token an jeder Position abgleiche. Die Reihenfolge der Token ist nicht wichtig. Wie kann ich das erreichen? Ich benutze Elasticsearch 0.90.5.

Beispiel:

I Index ein Dokument wie dieses.

{ 
    "field":"red car" 
} 

Ich verwende einen Synonym-Token-Filter, der Synonyme an den gleichen Positionen wie das ursprüngliche Token hinzufügt. So, jetzt auf dem Gebiet gibt es zwei Positionen:

  • Position 1: "rot"
  • Position 2: "Auto", "Automobil"

Meine Lösung für jetzt:

Um sicherzustellen, dass alle Positionen übereinstimmen, indexiere ich auch die maximale Position.

{ 
    "field":"red car", 
    "max_position": 2 
} 

Ich habe eine benutzerdefinierte Ähnlichkeit, die von DefaultSimilarity erstreckt und gibt 1 tf(), IDF() und lengthNorm(). Die resultierende Punktzahl ist die Anzahl der übereinstimmenden Begriffe in dem Feld.

Abfrage:

{ 
    "custom_score": { 
     "query": { 
      "match": { 
       "field": "a car is an automobile" 
      } 
     }, 
     "_script": "_score*100/doc[\"max_position\"]+_score" 
    }, 
    "min_score":"100" 
} 

Problem mit meiner Lösung:

Die obige Suche sollte das Dokument nicht überein, weil es keine Token "rot" in der Abfragezeichenfolge ist. Aber es passt, denn Elasticsearch zählt die Matches für Auto und Auto als zwei Matches und das ergibt eine Punktzahl von 2, was zu einem Skript-Ergebnis von 102 führt, das die "min_score" erfüllt.

Antwort

0

Wenn Sie 100% Übereinstimmungen mit den Abfragebegriffen garantieren möchten, können Sie minimum_should_match verwenden. Dies ist der häufigere Fall.


Leider ist in Ihrem Fall wünschen Sie 100% -Matches der indizierten Bedingungen zur Verfügung zu stellen.Dazu müssen Sie auf die Lucene-Ebene wechseln und eine benutzerdefinierte (java - here's boilerplate you can fork) Similarity-Klasse schreiben, da Sie Zugriff auf Low-level-Indexinformationen benötigen, die nicht der Query DSL:

pro Dokument/Feld in der Abfrage Stand abgetastet:

  • Anzahl der untersuchten Terms matched (lappen die Lucene Terminologie wird, ist es die der Koord() Methode der DefaultSimilarity Klasse verwendet)
  • Anzahl der Insgesamt analysierte Begriffe im Feld: Schau dir diesen Thread für ein Paar an Erent Möglichkeiten, um diese Informationen zu bekommen: How to count the number of terms for each document in lucene index?

dann Ihre individuelle Ähnlichkeit (Sie können sich wahrscheinlich sogar DefaultSimilarity verlängern) müssen Anfragen erfassen, wo Bedingungen angepasst < Gesamt Begriffe und multiplizieren ihre Punktzahl durch Null.

Da Abfrage und Index-Zeit-Analyse bereits auf dieser Ebene des Scoring geschehen sind, wird die Gesamtzahl der indizierten Begriffe bereits um Synonyme erweitert, wie die Abfrage Begriffe sollte die Vermeidung der falsch-positiven "ein Auto ist ein Auto " Problem oben.

Verwandte Themen