2017-06-08 6 views
0

Ich möchte eine Suche durchführen, die die folgenden Elemente implementiert.ElasticSearch/Nest Suche mit Synonymen, Plural und Fehlbuchungen

Gerade jetzt habe ich all dies durch regex implementiert und es ist bei weitem nicht alles abdeckt, und ich möchte wissen, wie viel ich Elasticsearch für diese stattdessen verwenden könnte:

  • Synonyme

    Meine Verständnis ist, dass dies implementiert wird, wenn der Index erstellt wird.

    indexSettings.Analysis.TokenFilters.Add ("Synonym", neu SynonymTokenFilter {Synonyme = neu [] {"tire => Reifen", "Aluminium => Aluminium"}, IgnoreCase = true, Tokenizer = "whitespace"});

    aber muss ich auch den Plural mit einschließen? oder,

  • Singular Worte

    (Schuhe und Schuh sollen eine identische Übereinstimmung sein) bedeutet das, dass ich in der Synonymliste ‚Schuhe‘ setzen? oder gibt es einen anderen Weg?

  • Kleine Fehlbuchstabierungen, Ersetzungen und Auslassungen sollten

    erlaubt werden, so dass 'Automobil', 'automoble' oder 'automoblie' entsprechen würde. Ich weiß nicht, ob das überhaupt möglich ist.

  • ignorieren alle Wörter stoppen

    jetzt alle 'der' Ich bin zu entfernen, 'this', 'mein' usw. durch regex

Alle meine Suchbegriffe sind plain English Wörter und Zahlen; nichts anderes ist erlaubt.

Antwort

2

All dies ist möglich durch configuring/writing a custom analyzer innerhalb Elasticsearch. Um jede Frage wiederum zu antworten:

Synonyme

Synonyme kann entweder Index Zeit angewendet werden, die Suchzeit oder beides. Es gibt Vor- und Nachteile in welcher auch immer betrachten Sie

  • Anwenden von Synonymen bei Index Zeit in schneller suchen führen wählen nähern im Vergleich zu bei Suchzeit Anwendung, auf Kosten von mehr Speicherplatz, die Indizierung Durchsatz und Leichtigkeit und Flexibilität des Hinzufügens/Entfernen vorhandener Synonyme
  • Das Anwenden von Synonymen zur Suchzeit ermöglicht eine größere Flexibilität auf Kosten der Suchgeschwindigkeit.

Auch müssen Sie die Größe der Synonymliste berücksichtigen und wie oft, wenn überhaupt, ändert sich. Ich würde versuchen, beides zu versuchen und zu entscheiden, welche am besten für Ihr Szenario und Ihre Anforderungen funktioniert.

Singular Worte (Schuhe und Schuh soll eine identische Übereinstimmung sein)

Sie betrachten stemming verwenden, können Plural und Singular Worte, um ihre Stammform zu reduzieren, einen algorithmischen oder Wörterbuch basierte stemmer verwenden. Beginnen Sie vielleicht mit der English Snowball stemmer und sehen Sie, wie es für Sie funktioniert.

Sie sollten auch überlegen, ob Sie auch die ursprüngliche Wortform indizieren müssen, z. sollten die Wortübereinstimmungen höher als die gestielten Wörter in ihrer Wurzelform sein?

Kleine Fehlbuchstabierungen, Ersetzungen und Auslassungen sollte

erlaubt werden mithilfe von Abfragen Betrachten Sie die fuzziness nutzen können Tipp- und Rechtschreibfehler zu behandeln. Wenn Rechtschreibfehler in den Indexdaten auftreten, sollten Sie eine Bereinigung vor der Indizierung in Erwägung ziehen. Wie pro alle Daten speichert, Müll rein, Müll raus :)

alle Wörter stoppen Ignorieren

Verwenden Sie ein English Stop token filter Stoppwörter zu entfernen.

zusammen all dies Einlochen, könnte ein Beispiel Analysator aussehen

void Main() 
{ 
    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200")); 
    var defaultIndex = "default-index"; 
    var connectionSettings = new ConnectionSettings(pool) 
     .DefaultIndex(defaultIndex); 

    var client = new ElasticClient(connectionSettings); 

    if (client.IndexExists(defaultIndex).Exists) 
     client.DeleteIndex(defaultIndex); 

    client.CreateIndex(defaultIndex, c => c 
     .Settings(s => s 
      .Analysis(a => a 
       .TokenFilters(t => t 
        .Stop("my_stop", st => st 
         .StopWords("_english_", "i've") 
         .RemoveTrailing() 
        ) 
        .Synonym("my_synonym", st => st 
         .Synonyms(
          "dap, sneaker, pump, trainer", 
          "soccer => football" 
         ) 
        ) 
        .Snowball("my_snowball", st => st 
         .Language(SnowballLanguage.English) 
        ) 
       ) 
       .Analyzers(an => an 
        .Custom("my_analyzer", ca => ca 
         .Tokenizer("standard") 
         .Filters(
          "lowercase", 
          "my_stop", 
          "my_snowball", 
          "my_synonym" 
         ) 
        ) 
       ) 
      ) 
     ) 
     .Mappings(m => m 
      .Map<Message>(mm => mm 
       .Properties(p => p 
        .Text(t => t 
         .Name(n => n.Content) 
         .Analyzer("my_analyzer") 
        ) 
       ) 
      ) 
     ) 
    ); 

    client.Analyze(a => a 
     .Index(defaultIndex) 
     .Field<Message>(f => f.Content) 
     .Text("Loving those Billy! Them is the maddest soccer trainers I've ever seen!") 
    ); 
} 

public class Message 
{ 
    public string Content { get; set; } 
} 

my_analyzer erzeugt die folgenden Token für oben

{ 
    "tokens" : [ 
    { 
     "token" : "love", 
     "start_offset" : 0, 
     "end_offset" : 6, 
     "type" : "<ALPHANUM>", 
     "position" : 0 
    }, 
    { 
     "token" : "those", 
     "start_offset" : 7, 
     "end_offset" : 12, 
     "type" : "<ALPHANUM>", 
     "position" : 1 
    }, 
    { 
     "token" : "billi", 
     "start_offset" : 13, 
     "end_offset" : 18, 
     "type" : "<ALPHANUM>", 
     "position" : 2 
    }, 
    { 
     "token" : "them", 
     "start_offset" : 20, 
     "end_offset" : 24, 
     "type" : "<ALPHANUM>", 
     "position" : 3 
    }, 
    { 
     "token" : "maddest", 
     "start_offset" : 32, 
     "end_offset" : 39, 
     "type" : "<ALPHANUM>", 
     "position" : 6 
    }, 
    { 
     "token" : "football", 
     "start_offset" : 40, 
     "end_offset" : 46, 
     "type" : "SYNONYM", 
     "position" : 7 
    }, 
    { 
     "token" : "trainer", 
     "start_offset" : 47, 
     "end_offset" : 55, 
     "type" : "<ALPHANUM>", 
     "position" : 8 
    }, 
    { 
     "token" : "dap", 
     "start_offset" : 47, 
     "end_offset" : 55, 
     "type" : "SYNONYM", 
     "position" : 8 
    }, 
    { 
     "token" : "sneaker", 
     "start_offset" : 47, 
     "end_offset" : 55, 
     "type" : "SYNONYM", 
     "position" : 8 
    }, 
    { 
     "token" : "pump", 
     "start_offset" : 47, 
     "end_offset" : 55, 
     "type" : "SYNONYM", 
     "position" : 8 
    }, 
    { 
     "token" : "ever", 
     "start_offset" : 61, 
     "end_offset" : 65, 
     "type" : "<ALPHANUM>", 
     "position" : 10 
    }, 
    { 
     "token" : "seen", 
     "start_offset" : 66, 
     "end_offset" : 70, 
     "type" : "<ALPHANUM>", 
     "position" : 11 
    } 
    ] 
} 
+0

Vielen Dank Russ, Sie haben keine Ahnung, wie hilfreich das ist! (Ich kann hier mit verwandten Fragen zurückkommen :)) – Thomas