2017-12-06 11 views
0

Ich implementiere eine Namenssuche mit den möglichen Feldern first_name, middle_initial und last_name. Abfragen sind normalerweise der Nachname zuerst, z. "Smith, A" bei der Suche nach "Smith, Ashley" statt "A Smith".Rangieren einer Teilfeldübereinstimmung mit einer Abfrage über einer vollständigen Übereinstimmung in einem anderen Feld

Meine Ergebnisse unerwünscht sind Scoring (Angela und Alex sollte über Robert und Ted sein):

  • "Smith, Roger A"
  • "Smith, Ted A"
  • „Smith, Angela D“
  • "Smith, Alex N"

ich habe eine Menge Dinge ausprobiert sowohl auf der Indizierung und Abfragen, und ich muss eine gewisse Menge an Unschärfe (Rechtschreibung und phonetische) enthalten. Die cross_match Abfrage + etwas Unschärfe über einen N-Gram-Analysator hat die meisten meiner Bedürfnisse außer diesem erfüllt. Edit: Die Liste oben ist von _score sortiert, so kann ich nicht nach anderen Dingen sortieren.

abfragen Beispiel, wo ich versuchte, zu sehen, ob die Indizierung der ersten & mittleren Namen zusammen einen Unterschied gemacht:

GET /_search 
{ 
    "query": { 
    "bool": { 
     "should": [ 
     { 
      "multi_match": { 
      "query": "smith, a", 
      "type": "cross_fields", 
      "fields": [ 
       "first_name_middle_initial^5", 
       "last_name^10" 
      ] 
      } 
     }, 
     { 
      "multi_match": { 
      "query": "smith, a", 
      "type": "cross_fields", 
      "fields": [ 
       "first_name_middle_initial.phonetic^2", 
       "last_name.phonetic^5" 
      ] 
      } 
     }, 
     { 
      "multi_match": { 
      "query": "smith, a", 
      "type": "cross_fields", 
      "fields": [ 
       "first_name_middle_initial.analyzed^2", 
       "last_name.analyzed^10" 
      ] 
      } 
     }, 
     { 
      "bool": { 
      "should": [ 
       { 
       "match": { 
        "last_name.word_start": { 
        "query": "smith, a", 
        "boost": 10, 
        "operator": "and", 
        "analyzer": "searchkick_word_search" 
        } 
       } 
       }, 
       { 
       "match": { 
        "last_name.word_start": { 
        "query": "smith, a", 
        "boost": 5, 
        "operator": "and", 
        "analyzer": "searchkick_word_search", 
        "fuzziness": 1, 
        "prefix_length": 0, 
        "max_expansions": 3, 
        "fuzzy_transpositions": true 
        } 
       } 
       } 
      ] 
      } 
     }, 
     { 
      "bool": { 
      "should": [ 
       { 
       "match": { 
        "first_name_middle_initial.word_start": { 
        "query": "smith, a", 
        "boost": 10, 
        "operator": "and", 
        "analyzer": "searchkick_word_search" 
        } 
       } 
       } 
      ] 
      } 
     } 
     ] 
    } 
    } 
} 

ich auch mit dem Boost-nestelte haben, zu übertönen versuchen, was auch immer auf die passende ist, mittlere Initiale, und sogar die mittlere Initiale in meiner Abfrage oder die Felder, die ich in der Abfrage verweise (z. B. first_name nur) für diese überhaupt nicht. Ich kann den mittleren Anfang nicht völlig ignorieren, falls es das differenzierende Feld ist.

Antwort

0

Nun, eines meiner Probleme könnte ein veralteter Index gewesen sein. Sonst schienen die Schlüssel einen Ngram-Analysator als einen meiner Übereinstimmungen zu verwenden und sicherzustellen, dass der middle_initial völlig unabhängig betrachtet wurde (sozusagen als Tiebreaker). Putting es in einer bool Unterabfrage war beabsichtigt - ich will es nicht und die anderen Unterabfragen in dieser Klausel berücksichtigt werden mit dem gleichen Gewicht wie die entspricht, wie this section of the elasticsearch guide.

Hier ist, was letztlich mein Problem gelöst:

Index Mapping:

{ 
    <snip> 
     "first_name": { 
     "type": "text", 
     "fields": { 
      "phonetic": { 
      "type": "text", 
      "analyzer": "dbl_metaphone" 
      }, 
      "word_start": { 
      "type": "text", 
      "analyzer": "searchkick_word_start_index" // includes "lowercase", "asciifolding", "searchkick_edge_ngram" (ngram from the start of the word) 
      } 
     } 
     }, 
     <snip> 
     "last_name": { 
     "type": "text", 
     "fields": { 
      "phonetic": { 
      "type": "text", 
      "analyzer": "dbl_metaphone" 
      }, 
      "word_start": { 
      "type": "text", 
      "analyzer": "searchkick_word_start_index" 
      } 
     } 
     }, 
     "middle_initial": { 
     "type": "keyword", 
     "fields": { 
      "analyzed": { 
      "type": "text", 
      "analyzer": "searchkick_index" // includes lowercase, asciifolding, shingles, stemmer 
      } 
     }, 
     "ignore_above": 30000 
     }, 
     <snip> 
    } 
    } 
} 

Abfrage:

{ 
    "query": { 
    "bool": { 
     "should": [ 
     [ 
      { 
      "multi_match": { 
       "query": "smith, s", 
       "type": "cross_fields", 
       "fields": [ 
       "first_name^2", 
       "last_name^3" 
       ], 
       "tie_breaker": 0.3 
      } 
      }, 
      { 
      "multi_match": { 
       "query": "smith, s", 
       "type": "cross_fields", 
       "fields": [ 
       "first_name.phonetic", 
       "last_name.phonetic" 
       ], 
       "tie_breaker": 0.3 
      } 
      }, 
      { 
      "multi_match": { 
       "query": "smith, s", 
       "type": "cross_fields", 
       "fields": [ 
       "first_name.word_start", 
       "last_name.word_start^2" 
       ], 
       "tie_breaker": 0.3 
      } 
      } 
     ], 
     { 
      "bool": { 
      "should": [ 
      <snip subquery for another field> 
       { 
       "match": { 
        "middle_initial.analyzed": { 
        "query": "s", 
        "operator": "and" 
        } 
       } 
       } 
      ] 
      } 
     } 
     ] 
    } 
    } 
} 
Verwandte Themen