2017-06-16 3 views
0

Ich bin ziemlich neu in Elasticsearch. Ich habe versucht, eine ziemlich einfache Suchfunktionalität zu implementieren, die Apostrophe ignoriert. Ich habe dieses Bit von documentation gefunden. Für die Umsetzung verwendete ich Nest Bibliothek:ElasticSearch (Nest) - Apostrophen ignorieren

[ElasticsearchType] 
public class MappingTest 
{ 
    [Text(Analyzer = "english")] 
    public string Title { get; set; } 
} 

Indexing/Suche:

var indexName = "testindex"; 
var connectionSettings = 
    new ConnectionSettings(
     new Uri("https://url.com")) 
     .DefaultIndex(indexName).EnableDebugMode();var client = new ElasticClient(connectionSettings); 

if (client.IndexExists(Indices.All, descriptor => descriptor.Index(indexName)).Exists) 
    client.DeleteIndex(indexName); 

var response = client.CreateIndex(indexName, i => new CreateIndexDescriptor(indexName) 
    .Mappings(ms => ms 
     .Map<MappingTest>(m => m.AutoMap()) 
    ).Settings(s => s 
     .Analysis(a => a 
      .Analyzers(aa => aa 
       .Custom("english", ca => ca 
        .Tokenizer("standard") 
        .Filters("english_possessive_stemmer", "lowercase") 
       ) 
      ) 
      .TokenFilters(
       t => t.Stemmer("english_possessive_stemmer", d => d.Language("possessive_english"))) 
      .TokenFilters(
       t => t.Stemmer("english_stemmer", d => d.Language("english"))) 
      .TokenFilters(
       t => t.Stop("english_stop", d => d.StopWords("_english_"))) 
     ) 
    )); 


var obj = new MappingTest() { Title = "Example's" }; 


var indexResponse = client.Index(obj); 

var term = "example"; 

QueryContainer commonQuery = 
    Query<MappingTest>.QueryString(qs => qs.Query(term).DefaultField(f => f.Title)); 

var searchResponse = client.Search<MappingTest>(s => s.Query(x => commonQuery)); 
var debug = searchResponse.DebugInformation;  

habe ich versucht, ein paar Ansätze, aber jedes Mal, wenn ich erhalte keine Ergebnisse. Ich würde eine Hilfe schätzen.

Antwort

0

Ein paar Dinge:

  1. Sie brauchen nicht Ihren eigenen "english" Analysator zu spezifizieren, wie es in Elasticsearch gebaut ist. Wenn Sie darauf basierend implement your own analyzer möchten, dann müssten Sie es angeben, wie Sie sind. In Ihrem Fall hier, glaube ich nicht, dass Sie Ihre eigenen angeben möchten, da Ihr benutzerdefinierter Analysator nur Token-Filter english_possessive_stemmer und lowercase verwendet.
  2. Mehrere Anrufe zu .TokenFilters() bedeutet, dass nur der letzte Anruf gewinnt; Anrufe durchführen Zuordnung im Allgemeinen in NEST, so dass Sie für das Feld verwendet

    .TokenFilters(t => t 
        .Stemmer("english_possessive_stemmer", d => d.Language("possessive_english")) 
        .Stemmer("english_stemmer", d => d.Language("english")) 
        .Stop("english_stop", d => d.StopWords("_english_"))) 
    
  3. Das Text Attribut auf der POCO Eigenschaft Title den Analysator bestimmt

  4. Ein indiziertes Dokument nicht zur Verfügung steht für die Suche erst nach dem Refresh wollen würden Das Intervall ist abgelaufen (Standard ist 1 Sekunde) und das neu indizierte Dokument wird in ein neues Segment geschrieben. In Ihrem Beispiel vermuten, dass ich Ihre Suche ausgeführt wird, bevor das Dokument für den Index zur Verfügung

ich die mit Analysatoren zu spielen Analyze API Verwendung würde empfehlen. Sie können den Index und die Zuordnung für Ihre Art erstellen, analysieren dann ein Stück Text, um die Zuordnung für einen bestimmten Bereich unter Verwendung

void Main() 
{ 
    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200")); 
    var defaultIndex = "default-index"; 
    var connectionSettings = new ConnectionSettings(pool) 
     .DefaultIndex(defaultIndex) 
     .PrettyJson() 
     .EnableDebugMode(response => 
      { 
       if (response.RequestBodyInBytes != null) 
       { 
        Console.WriteLine(
         $"{response.HttpMethod} {response.Uri} \n" + 
         $"{Encoding.UTF8.GetString(response.RequestBodyInBytes)}"); 
       } 
       else 
       { 
        Console.WriteLine($"{response.HttpMethod} {response.Uri}"); 
       } 

       Console.WriteLine(); 

       if (response.ResponseBodyInBytes != null) 
       { 
        Console.WriteLine($"Status: {response.HttpStatusCode}\n" + 
          $"{Encoding.UTF8.GetString(response.ResponseBodyInBytes)}\n" + 
          $"{new string('-', 30)}\n"); 
       } 
       else 
       { 
        Console.WriteLine($"Status: {response.HttpStatusCode}\n" + 
          $"{new string('-', 30)}\n"); 
       } 
      }); 

    var client = new ElasticClient(connectionSettings); 

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

    client.CreateIndex(defaultIndex, i => i 
     .Mappings(ms => ms 
      .Map<MappingTest>(m => m 
       .AutoMap() 
      ) 
     ) 
    ); 

    client.Analyze(a => a 
     .Index(defaultIndex) 
     .Field<MappingTest>(f => f.Title) 
     .Text("Example's") 
    ); 
} 

[ElasticsearchType] 
public class MappingTest 
{ 
    [Text(Analyzer = "english")] 
    public string Title { get; set; } 
} 

Sie können sehen, dass der Analysator für Example's

{ 
    "tokens" : [ 
    { 
     "token" : "exampl", 
     "start_offset" : 0, 
     "end_offset" : 9, 
     "type" : "<ALPHANUM>", 
     "position" : 0 
    } 
    ] 
} 
das folgende Token zurückgibt
Verwandte Themen