I'm using Elasticsearch 5.5 on AWS.
With a type (with NEST mapping attributes) that looks like this:
[ElasticsearchType]
public class MyType
{
public const string AutocompleteAnalyzer = "autocomplete";
public const string StopWordsAnalyzer = "stopwords";
public string Id { get; set; }
[Text(Analyzer = AutocompleteAnalyzer, SearchAnalyzer = StopWordsAnalyzer)]
public string Name { get; set; }
[Keyword]
public string NotAnalyzedProperty { get; set; }
[Text(Analyzer = AutocompleteAnalyzer, SearchAnalyzer = StopWordsAnalyzer)]
public string OtherTextProperty { get; set; }
}
The index is created like this:
var indexDescriptor = new CreateIndexDescriptor(IndexName)
.Settings(s => s
.Analysis(a => a
.TokenFilters(t => t.EdgeNGram("autocomplete_filter", e => e.MinGram(3).MaxGram(20)))
.Analyzers(aa => aa
.Custom(MyType.AutocompleteAnalyzer, c => c.Tokenizer("standard").Filters("lowercase", "autocomplete_filter"))
.Standard(MyType.StopWordsAnalyzer, w => w.StopWords(_stopWords)))))
.Mappings(ms => ms.Map<MyType>(m => m.AutoMap().Properties(p => p.Text(f => f.Name(t => t.Name).Fields(ff => ff
.Text(tt => tt
.Name(AutocompleteField)
.Analyzer(MyType.AutocompleteAnalyzer))
.Keyword(k => k
.Name(KeywordField)
.IgnoreAbove(256)))))));
var createIndexResponse = await _elasticClient.CreateIndexAsync(indexDescriptor, cancellationToken);
When I run this search:
{
"size":10,
"sort":[
{"_score":{"order":"desc"}},
{"name.keyword":{"order":"asc"}},
{"id.keyword":{"order":"asc"}}],
"query":{
"bool":{
"must":[{
"multi_match":{
"type":"best_fields",
"query":"raining",
"fields":[
"name.autocomplete",
"otherTextProperty"]}}],
"filter":[{
"bool":{
"must":[{
"match":{
"notAnalyzedProperty":{"query":"Test"}}}]}}]}}}
It matches any document that contains any word starting with "rai", instead of just those that contain "raining". If I add "analyzer":"stopwords"
to the multi_match query, it works as expected, and only finds documents containing "raining".
My understanding from the docs, and also other questions (https://stackoverflow.com/questions/36051750/elasticsearch-multi-match-cross-fields-query-with-different-query-analyzers), is that the search should default to the search analyzer defined in the field mappings, but it appears to be using the index analyzer instead.
I assume there is something wrong with my mapping, but I can't see what. Any ideas?