Kenny Steen
Kenny Steen

Reputation: 67

Elasticsearch 6.3 - How to Sort on an Analyzed field?

So, I have found examples of this for older versions of Elastic, but due to the syntax changing, I haven't been able to translate those solutions into the 6.3 Syntax.

I have a field, ShowName (String), which I have applied an N-Gram Analyzer to. The problem is that I also need to sort by that field. Before I added the analyzer, I got the Keyword suffix sub property and was able to sort no bother, however, since adding the analyzer, I now don't have access to that keyword sub property.

I have tried decorating the property in my model with both the [Text(Analyzer = "nGram_analyzer")]) and Keyword properties, but when creating the index I get an error saying:

Multiple custom attributes of the same type found.

I then tried explicitly adding both fields in the mappings while creating my index (code below) and while this creates both fields, I am still unable to sort by the keyword suffixed field. Can anyone point out where I'm going wrong?

var createIndexResponse = client.CreateIndex(shows, c => c
            .Settings(s => s
                .Analysis(a => a
                    .TokenFilters(t => t.NGram("nGram_filter", ng => ng.MinGram(3).MaxGram(10)))
                    .Analyzers(aa => aa
                        .Custom("nGram_analyzer", cc => cc
                            .Tokenizer("whitespace")
                            .Filters(nGramFilters1)
                        )
                    )
                )
            )
            .Mappings(ms => ms
                .Map<ShowElasticSearchModel>(m => m
                    .AutoMap<ShowElasticSearchModel>()
                    .Properties(p => p
                        .Text(t => t
                            .Name(n => n.ShowName)
                            .Analyzer("nGram_analyzer")
                            .Fields(fs => fs
                                .Text(tt => tt.Name(nn => nn.ShowName.Suffix("keyword")))
                            )
                        )
                    )
                )
            )
        );

Edit: Following on from the answer received, the final syntax for the code block is as follows (now contains multiple Multi Fields within the code).

var createIndexResponse = client.CreateIndex(shows, c => c
            .Settings(s => s
                .Analysis(a => a
                    .TokenFilters(t => t.NGram("nGram_filter", ng => ng.MinGram(3).MaxGram(10)))
                    .Analyzers(aa => aa
                        .Custom("nGram_analyzer", cc => cc
                            .Tokenizer("whitespace")
                            .Filters(nGramFilters1)
                        )
                    )
                )
            )
            .Mappings(ms => ms
                .Map<ShowElasticSearchModel>(m => m
                    .AutoMap<ShowElasticSearchModel>()
                    .Properties(p => p
                        .Text(t => t
                            .Name(n => n.ShowName)
                            .Analyzer("nGram_analyzer")
                            .Fields(ff => ff
                                .Keyword(k => k
                                    .Name(n => n.ShowName.Suffix("keyword"))
                                )
                            )
                        )
                        .Text(t => t
                            .Name(n => n.Organisation)
                            .Analyzer("nGram_analyzer")
                            .Fields(ff => ff
                                .Keyword(k => k
                                    .Name(n => n.Organisation.Suffix("keyword"))
                                )
                            )
                        )
                        .Text(t => t
                            .Name(n => n.Venues)
                            .Analyzer("nGram_analyzer")
                            .Fields(ff => ff
                                .Keyword(k => k
                                    .Name(n => n.Venues.Suffix("keyword"))
                                )
                            )
                        )
                    )
                )
            )
        );

Upvotes: 1

Views: 1142

Answers (1)

Alexey Prudnikov
Alexey Prudnikov

Reputation: 1123

String field type has been split to keyword and text types since Elasticsearch 5.0. Text fields can't be used for sorting, so you need to create multi-field: with type text for full text search and with type keyword for aggregations and sorting.

But in your example you create two text fields, and use keyword as field name suffix rather than field type (as far as I can understand C# syntax).

Upvotes: 1

Related Questions