Пользователь, который вызывает мой API отдыха, должен иметь возможность указать тип места, а затем предложить название.
Тип места должен быть точным, в то время как поиск по названию использует весь потенциал поиска elaticsearch.
Я использую NEST (последняя версия nuget) и Elastic 6.4.
My Api имеет 2 параметра:
1. запрос: поиск текстового поиска
2. placetypes: массив для определения желаемых «категорий» документов в предложении
Предложение названия места с параметром Query работает хорошо,
но я не знаю, как добавить условие placetype.
Отображение гнезда:
return map
.Dynamic(false)
.Properties(props => props
.Keyword(n => n
.Name(p => p.Id))
.Text(n => n
.Name(p => p.PlaceType))
.Completion(n => n
.Name(p => p.PlaceName)
.Analyzer("autocompletion_indexation"))
.Completion(n => n
.Name(p => p.Address)
.Analyzer("autocompletion_indexation"))
.GeoPoint(loc =>
{
loc.Name(location => location.Coordinates);
return loc;
}));
Анализ гнездаDescriptor:
return analysis
.CharFilters(c => c
.HtmlStrip("html_strip")
)
.Tokenizers(t => t
.EdgeNGram("custom_ngram", descriptor =>
{
descriptor.MinGram(2);
descriptor.MaxGram(10);
descriptor.TokenChars(new List<TokenChar> { TokenChar.Letter, TokenChar.Digit });
return descriptor;
}
))
.TokenFilters(tf => tf
.Lowercase("lowercase")
.WordDelimiter("word_delimiter", wd =>wd
.SplitOnNumerics()
.SplitOnCaseChange()
)
.AsciiFolding("asciifolding", af => af
.PreserveOriginal(false)
)
.Elision("elision", e => e
.Articles("l", "d", "o")
)
.Synonym("address_synonym", sy => sy
.Synonyms(GetSynonyms())
.Tokenizer("standard")
.Tokenizer("whitespace")
)
.Stop("french_stop", fs => fs
.StopWords("_french_"))
.Stemmer("french_stemmer", fs => fs
.Language("light_french")
)
)
.Analyzers(an => an
.Custom("autocompletion_indexation", c => c
.Tokenizer("custom_ngram")
.Tokenizer("standard")
.Tokenizer("whitespace")
.CharFilters("html_strip")
.Filters("address_synonym",
"lowercase",
"asciifolding",
"elision",
"word_delimiter",
"stop",
"french_stemmer",
"french_stop")
));
Функция подсказки / поиска:
public Task<List<Place>> SuggestDocuments(CancellationToken cancellationToken, string query, params string[] placeTypes)
{
var search = new SearchDescriptor<Place>()
.From(0)
.Size(10)
.Index(PlaceDataService.DefaultPostalAddressIndexName)
.Query(q => q
.MultiMatch(mm => mm
.Query(query)
.Fuzziness(Fuzziness.Auto)
.Fields(fields => fields
.Field(f => f.PlaceName)
)));
var searchResults = _elasticClient.SearchAsync<Place>(search, cancellationToken);
return Task.Run(() => searchResults.Result.Documents.ToList(), cancellationToken);
}