Я использовал Elastic Search для проекта, но нахожу результат Snowball Analyzer немного странным.
Ниже приведен мой пример картирования.
$myTypeMapping = array(
'_source' => array(
'enabled' => true
),
'properties' => array(
'id' => array(
'type' => 'integer',
'index' => 'not_analyzed'
),
'name' => array(
'type' => 'string',
'analyzer' => 'snowball',
'boost' => 2.0
),
'food_types' => array(
'type' => 'string',
'analyzer' => 'keyword'
),
'location' => array(
'type' => 'geo_point',
"geohash_precision"=> 4
),
'city' => array(
'type' => 'string',
'analyzer' => 'keyword'
)
)
);
$indexParams['body']['mappings']['online_pizza'] = $myTypeMapping;
// Create the index
$elastic_client->indices()->create($indexParams);
На вопрос http://localhost:9200/online_pizza/online_pizza/_mapping
Я получаю следующие результаты,
{
"online_pizza": {
"properties": {
"city": {
"type": "string",
"analyzer": "keyword"},
"food_types": {
"type": "string",
"analyzer": "keyword"},
"id": {
"type": "integer"},
"location": {
"type": "geo_point",
"geohash_precision": 4
},
"name": {
"type": "string",
"boost": 2,
"analyzer": "snowball"}
}
}
}
Мой вопрос, у меня есть данные, которые имеют Name
поле как «Милан». При запросе «Милано» я получаю желаемый результат, но если я запрашиваю «Милан» или «Мил», я не получаю никакого результата.
{
"query": {
"query_string": {
"default_field": "name",
"query": "Milan"}
}
}
Я также пытался анализировать снежный ком во время запросов, без помощи.
{
"query": {
"query_string": {
"default_field": "name",
"query": "Milan",
"analyzer": "snowball"}
}
}
Второй вопрос — поиск по ключевым словам чувствителен к регистру, например, Pizza! = Pizza. Как мне избежать этого?
Спасибо,
snowball
Стеммер не хочет точных слов. Если вы попробуете это с jumping
, это выводит jump
как и ожидалось.
Тем не менее, в зависимости от случая, ваше слово может быть недопустимым, поскольку оно не соответствует ни одному правилу.
Если вы используете analyze
Конечная точка API (больше информации Вот), вы увидите, что анализируя Milano
с snowball
анализатор выдает токен milano
:
GET _analyze?analyzer=snowball&text=Milano
Выход :
{
"tokens": [
{
"token": "milano",
"start_offset": 0,
"end_offset": 6,
"type": "<ALPHANUM>",
"position": 1
}
]
}
Затем, используя тот же анализатор снежного кома на Mil
как это :
GET _analyze?analyzer=snowball&text=Mil
дает вам этот токен:
{
"tokens": [
{
"token": "mil",
"start_offset": 0,
"end_offset": 3,
"type": "<ALPHANUM>",
"position": 1
}
]
}
Вот почему поиск «milan» или «mil» не будет соответствовать документам «Milano»: он не соответствует milano
термин хранится в индексе.
По второму вопросу вы можете подготовить custom
объединение анализатора keyword
токенизатор и lowercase
tokenfilter, чтобы в вашем поиске по ключевым словам не учитывался регистр (если вы используете тот же анализатор во время поиска):
POST index_name
{
"analysis": {
"analyzer": {
"case_insensitive_keyword": {
"type": "custom",
"tokenizer": "keyword",
"filter": ["lowercase"]
}
}
}
}
Тестовое задание :
GET analyse/_analyze?analyzer=case_insensitive_keyword&text=Choo Choo
Выход :
{
"tokens": [
{
"token": "choo choo",
"start_offset": 0,
"end_offset": 9,
"type": "word",
"position": 1
}
]
}
Я надеюсь, что я достаточно ясно в моих объяснениях 🙂
Других решений пока нет …