Исходя из ответа Расса Кэма выше (вариант 2), этого руководства Elasticsearch , а также этого документа , я получил следующее решение:
PUT my_index
{
"settings": {
"analysis": {
"filter": {
"edge_ngram_token_filter": {
"type": "edge_ngram",
"min_gram": 2,
"max_gram": 10
},
"additional_stop_words": {
"type": "stop",
"stopwords": ["your"]
},
"english_stemmer": {
"type": "stemmer",
"language": "english"
},
"english_possessive_stemmer": {
"type": "stemmer",
"language": "possessive_english"
}
},
"char_filter": {
"my_char_filter": {
"type": "mapping",
"mappings": [
"C# => csharp",
"c# => csharp"
]
}
},
"analyzer": {
"result_suggester_analyzer": {
"type": "custom",
"tokenizer": "standard",
"char_filter": [ "html_strip", "my_char_filter" ],
"filter": [
"english_possessive_stemmer",
"lowercase",
"asciifolding",
"stop",
"additional_stop_words",
"english_stemmer",
"edge_ngram_token_filter",
"unique"
]
}
}
}
}
}
Запрос для проверки этого решения:
POST my_index/_analyze
{
"analyzer": "result_suggester_analyzer",
"text": "C# & SQL are great languages. K2 is the mountaineer's mountain. Your house-décor is à la Mode"
}
Я бы получил эти токены (NGrams):
cs, csh, csha, cshar, csharp, sq, sql, gr, gre, grea, great, la, lan, lang,
langu, langua, languag, k2, mo, mou, moun, mount, mounta, mountai, mountain,
ho, hou, hous, hous, de, dec, deco, decor, mod, mode
Что следует отметить здесь:
- Я использую фильтр
stop
, который является английским языком по умолчанию
фильтр и блокирует are, is, the
- но не your
.
- Я определил
additional_stop_words
, который останавливается your
- Я использую встроенные
english
& possessive_english
стеммеры, которые бы токенизировали слова: 1030 * гора но не альпинизм .
- Я определил
mapped_words_char_filter
, который конвертирует C # в csharp, без этого c # не будет действительным токеном ... (этот параметр не будет токенизировать F #)
- Я использую встроенный
html_strip
, char_filter
, который преобразует &
в &, и он игнорируется, так как наша min_gram = 2
- Мы используем встроенный
asciifolding
фильтр токенов, поэтому декор маркируется как decor .
Это код NEST для вышеуказанного:
var createIndexResponse = ElasticClient.CreateIndex(IndexName, c => c
.Settings(st => st
.Analysis(an => an
.Analyzers(anz => anz
.Custom("result_suggester_analyzer", cc => cc
.Tokenizer("standard")
.CharFilters("html_strip", "mapped_words_char_filter")
.Filters(new string[] { "english_possessive_stemmer", "lowercase", "asciifolding", "stop", "english_stemmer", "edge_ngram_token_filter", "unique" })
)
)
.CharFilters(cf => cf
.Mapping("mapped_words_char_filter", md => md
.Mappings(
"C# => csharp",
"c# => csharp"
)
)
)
.TokenFilters(tfd => tfd
.EdgeNGram("edge_ngram_token_filter", engd => engd
.MinGram(2)
.MaxGram(10)
)
.Stop("additional_stop_word", sfd => sfd.StopWords(new string[] { "your" }))
.Stemmer("english_stemmer", esd => esd.Language("english"))
.Stemmer("english_possessive_stemmer", epsd => epsd.Language("possessive_english"))
)
)
)
.Mappings(m => m.Map<AdDocument>(d => d.AutoMap())));