анализатор / токенизатор ngram elasticsearch не работает?

#elasticsearch #nest

#elasticsearch #nest

Вопрос:

похоже, что токенизатор ngram не работает или, возможно, мое понимание / использование его неверно.

мой токенизатор выполняет mingram из 3 и maxgram из 5. я ищу термин «мадонна», который определенно есть в моих документах в разделе artists.name . я могу найти этот термин с помощью других методов (используя simple analyzer и связанные с ним), но не используя ngram.

чего я пытаюсь достичь с помощью ngram, так это поиска имен и учета орфографических ошибок.

пожалуйста, посмотрите сокращенную версию моих сопоставлений, моих настроек и моего запроса, и если у вас есть какие-либо идеи, пожалуйста, дайте мне знать — это сводит меня с ума!

Настройки…

 {
   "myindex": {
      "settings": {
         "index": {
            "analysis": {
               "analyzer": {                  
                  "ngramAnalyzer": {
                     "type": "custom",
                     "filter": [
                        "lowercase"
                     ],
                     "tokenizer": "nGramTokenizer"
                  }  
               },
               "tokenizer": {
                  "nGramTokenizer": {
                     "type": "nGram",
                     "min_gram": "3",
                     "max_gram": "5"
                  }
               }
            },
            "number_of_shards": "5",
            "number_of_replicas": "1",
            "version": {
               "created": "1020199"
            },
            "uuid": "60ggSr6TREaDTItkaNUagg"
         }
      }
   }
}
  

сопоставления …

 {
   "myindex": {
      "mappings": {
         "mytype": {
            "properties": { 
               "artists.name": {
                  "type": "string",
                  "analyzer": "simple",
                  "fields": {
                     "ngram": {
                        "type": "string",
                        "analyzer": "ngramAnalyzer"
                     },
                     "raw": {
                        "type": "string",
                        "index": "not_analyzed"
                     }
                  }
               }
            }
         }
      }
   }
}
  

запрос …

 {"query": {"match": {"artists.name.ngram": "madonna"}}}
  

документ …

 {
   "_index": "myindex",
   "_type": "mytype",
   "_id": "602537592951",
   "_version": 1,
   "found": true,
   "_source": {
      "artists": [
         {
            "name": "Madonna",
            "id": "P    64565"
         }
      ]
   }
}
  

РЕДАКТИРОВАТЬ
кстати, этот запрос работает (без ngram):

 {"query": {"match": {"artists.name": "madonna"}}}
  

очевидно, это как-то связано с вложенным объектом здесь. я, по-видимому, неправильно применяю ngram к вложенному объекту.

идеи?

Ответ №1:

хорошо — я понял это. я действительно надеюсь, что это поможет кому-то, потому что это сводило меня с ума.

вот как выглядело мое отображение:

 {
   "myindex": {
      "mappings": {
         "mytype": {
            "properties": {               
               "artists": {
                  "properties": {
                     "id": {
                        "type": "string"
                     },
                     "name": {
                        "type": "string",
                        "analyzer": "ngramAnalyzer",
                        "fields": {
                           "raw": {
                              "type": "string",
                              "index": "not_analyzed"
                           }
                        }
                     }
                  }
               }
            }
        }
    }
}
  

и вот как я это сделал, используя синтаксис Nest…

сначала у меня был подтип (класс) с именем Person, который имеет имя и идентификатор, которые выглядят следующим образом (POCO)…

 [Serializable]
public class Person
{
    public string Name { get; set; }
    [ElasticProperty(Analyzer = "fullTerm", Index = FieldIndexOption.not_analyzed)]
    public string Id { get; set; }
}
  

и затем мое отображение выглядело примерно так…

 .AddMapping<MyIndex>(m => m
.MapFromAttributes()
.Properties(props =>
{
    props           
        .Object<Person>(x => x.Name("artists")
        .Properties(pp => pp
            .MultiField(
                mf => mf
                .Name(s => s.Name)
                .Fields(f => f
                    .String(s => s.Name(o => o.Name).Analyzer("ngramAnalyzer"))
                    .String(s => s.Name(o => o.Name.Suffix("raw")).Index(FieldIndexOption.not_analyzed))
                )
            )
        )
    )
)
  

Примечание: объект здесь, который указывает, что это другой объект под моим типом «художники».

Спасибо, я!!!

редактировать: сопоставления curl могут быть примерно такими…

 curl-XPOST"http://localhost:9200/yourindex/_mappings"-H'Content-Type:application/json'-d'{"myindex":{"mappings":{"mytype":{"properties":{"artists":{"properties":{"id":{"type":"string"},"name":{"type":"string","analyzer":"ngramAnalyzer","fields":{"raw":{"type":"string","index":"not_analyzed"}}}}}}}}}}'
  

Комментарии:

1. Не могли бы вы рассказать мне, каким должно быть окончательное сопоставление и запрос в синтаксисе curl