4

Im very very new to elasticsearch using the nest client, I am creating an index with a custom analyzer, however when testing using analyze it does not seem to use the custom analyzer. Mainly no edgengram tokens appear. Is there anything I am missing that would make my custom analyser the default for the index? When I check my mappings using elastichq they show my custom analyzer.

ConnectionSettings settings = new ConnectionSettings(new Uri("http://localhost:9200"),    defaultIndex: "forum-app");

 IndexSettings indsettings = new IndexSettings();

   var an = new CustomAnalyzer();

   an.CharFilter = new List<string>();
   an.CharFilter.Add("html_strip");
   an.Tokenizer = "edgeNGram";
   an.Filter = new List<string>();
   an.Filter.Add("standard");
   an.Filter.Add("lowercase");
   an.Filter.Add("stop");

indsettings.Analysis.Tokenizers.Add("edgeNGram", new Nest.EdgeNGramTokenizer
{
    MaxGram = 15,
    MinGram = 3
});

indsettings.Analysis.Analyzers.Add("forumanalyzer", an);

ElasticClient client = new ElasticClient(settings);

client.CreateIndex("forum-app", c => c
.NumberOfReplicas(0)
.NumberOfShards(1)
.AddMapping<Forum>(e => e.MapFromAttributes())
.Analysis(analysis => analysis
.Analyzers(a => a
.Add("forumanalyzer", an) 
)));        

//To index I just do this       
client.Index(aForum);
1
  • I got NullReferenceException trying to use your code. Analysis property is null. That why I can't add my custom analyzer to the Analyzers. Did you have that problem? @yaly_cu Commented Feb 2, 2017 at 12:36

2 Answers 2

6

You've added your custom analyzer to your index, but now you need to apply it your fields. You can do this on a field mapping level:

client.CreateIndex("forum-app", c => c
    .NumberOfReplicas(0)
    .NumberOfShards(1)
    .AddMapping<Forum>(e => e
        .MapFromAttributes()
        .Properties(p => p
            .String(s => s.Name(f => f.SomeProperty).Analyzer("formanalyzer")))
    )
    .Analysis(analysis => analysis
        .Analyzers(a => a
            .Add("forumanalyzer", an)
        )
    )
);

Or you can apply it to all fields by default by setting it as the default analyzer of your index:

client.CreateIndex("forum-app", c => c
    .NumberOfReplicas(0)
    .NumberOfShards(1)
    .AddMapping<Forum>(e => e.MapFromAttributes())
    .Analysis(analysis => analysis
        .Analyzers(a => a
            .Add("default", an)
        )
    )
);

More info here in regards to analyzer defaults.

Sign up to request clarification or add additional context in comments.

Comments

2

Add a custom analyzer:

var indexSettings = new IndexSettings
{
    NumberOfReplicas = 0, // If this is set to 1 or more, then the index becomes yellow.
    NumberOfShards = 5
};

indexSettings.Analysis = new Analysis();
indexSettings.Analysis.Analyzers = new Analyzers();
indexSettings.Analysis.TokenFilters = new TokenFilters();

var customAnalyzer = new CustomAnalyzer
{
    //CharFilter = new List<string> { "mapping " }, 
    Tokenizer = "standard",
    Filter = new List<string> { "lowercase", "asciifolding" }
};

indexSettings.Analysis.Analyzers.Add("customAnalyzerLowercaseSynonymAsciifolding", customAnalyzer);

And then when creating the index, you specify the analyzer:

var indexConfig = new IndexState
{
    Settings = indexSettings
};

 var createIndexResponse = elasticClient.CreateIndex(indexName, c => c
   .InitializeUsing(indexConfig)
   .Mappings(m => m
       .Map<ElasticsearchModel>(mm => mm
           .Properties(
           p => p
           .Text(t => t.Name(elasticsearchModel => elasticsearchModel.StringTest).Analyzer("customAnalyzerLowercaseSynonymAsciifolding"))                          
           )
       )
   )
);

elasticClient.Refresh(indexName);

And then you query it with something like:

var response = elasticClient.Search<ElasticsearchModel>(s => s
        .Index(indexName)
        .Query(q => q
              .SimpleQueryString(qs => qs
                  .Fields(fs => fs
                       .Field(f => f.StringTest, 4.00)
                  )
                  .Query(query)
                 )
               )
           );

var results = new List<ElasticsearchModel>();
results = response.Hits.Select(hit => hit.Source).ToList();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.