Точки в поле не используются для разделения слова для анализатора

#elasticsearch

#elasticsearch

Вопрос:

У меня есть следующее отображение для индексных документов (упрощенное)

 {
    "documents": {
        "mappings": {
            "document": {
                "properties": {
                    "filename": {
                        "type": "string",
                        "fields": {
                            "lower_case_sort": {
                                "type": "string",
                                "analyzer": "case_insensitive_sort"
                            },
                            "raw": {
                                "type": "string",
                                "index": "not_analyzed"
                            }
                        }
                    }
                }
            }
        }
    }
}
  

Я поместил два документа в этот индекс

 {
    "_index": "documents",
    "_type": "document",
    "_id": "777",
    "_source": {
        "filename": "text.txt",
    }
}
  

 {
    "_index": "documents",
    "_type": "document",
    "_id": "888",
    "_source": {
        "filename": "text 123.txt",
    }
}
  

Выполняя запрос query_string или simple_query_string к «тексту», я ожидал бы получить оба документа обратно. Они должны совпадать из-за имен файлов «text.txt » и «текст 123.txt «.

 http://localhost:9200/defiant/_search?q=text
  

Однако я нахожу документ только с названием «тест 123.txt » — «test.txt » найдено только при поиске «test.*» или «test.txt » или «test.???» — я ДОЛЖЕН добавить точку в имя файла.

Это мой результат объяснения по идентификатору документа 777 (text.txt )

 curl -XGET 'http://localhost:9200/documents/document/777/_explain' -d '{"query": {"query_string" : {"query" : "text"}}}'
  

—>

 {
    "_index": "documents",
    "_type": "document",
    "_id": "777",
    "matched": false,
    "explanation": {
        "value": 0.0,
        "description": "Failure to meet condition(s) of required/prohibited clause(s)",
        "details": [{
            "value": 0.0,
            "description": "no match on required clause (_all:text)",
            "details": [{
                "value": 0.0,
                "description": "no matching term",
                "details": []
            }]
        }, {
            "value": 0.0,
            "description": "match on required clause, product of:",
            "details": [{
                "value": 0.0,
                "description": "# clause",
                "details": []
            }, {
                "value": 0.47650534,
                "description": "_type:document, product of:",
                "details": [{
                    "value": 1.0,
                    "description": "boost",
                    "details": []
                }, {
                    "value": 0.47650534,
                    "description": "queryNorm",
                    "details": []
                }]
            }]
        }]
    }
}
  

Я испортил отображение? Я бы подумал, что ‘.’ анализируется как разделитель терминов при индексации документа…

Отредактировано: Настройки case_insensitive_sort

 {
    "documents": {
        "settings": {
            "index": {
                "creation_date": "1473169458336",
                "analysis": {
                    "analyzer": {
                        "case_insensitive_sort": {
                            "filter": [
                                "lowercase"
                            ],
                            "tokenizer": "keyword"
                        }
                    }
                }
            }
        }
    }
}
  

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

1. не могли бы вы предоставить настройки (маркеры, фильтры) case_insensitive_sort ?

2. Обновлен исходный вопрос. Не уверен, что это актуально, поскольку к запросу должен применяться анализатор по умолчанию. «case_insensitive_sort» используется только в подполе filename. Соответственно. имя файла. lower_case_sort.

Ответ №1:

Это было бы ожидаемым поведением standard analyzer (анализатора по умолчанию), поскольку он использует стандартный токенизатор, и в соответствии с используемым им алгоритмом точка не рассматривается как разделяющий символ.

Вы можете проверить это с помощью analyze api

 curl -XGET 'localhost:9200/_analyze' -d '
{
  "analyzer" : "standard",
  "text" : "test.txt"
}'
  

генерируется только один токен

 {
  "tokens": [
    {
      "token": "test.txt",
      "start_offset": 0,
      "end_offset": 8,
      "type": "<ALPHANUM>",
      "position": 0
    }
  ]
}
  

Вы могли бы использовать фильтр замены символов по шаблону, чтобы заменить точку пустым пространством.

 {
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "standard",
          "char_filter": [
            "replace_dot"
          ]
        }
      },
      "char_filter": {
        "replace_dot": {
          "type": "pattern_replace",
          "pattern": "\.",
          "replacement": " "
        }
      }
    }
  }
}
  

Вам придется переиндексировать ваши документы, и тогда вы получите желаемые результаты. Analyze api очень удобен для проверки того, как ваши документы хранятся в инвертированном индексе.

Обновить

Вам нужно будет указать имя поля, по которому вы хотите выполнить поиск. Следующий запрос ищет текст в _all поле, которое по умолчанию использует стандартный анализатор.

 http://localhost:9200/defiant/_search?q=text
  

Я думаю, что следующий запрос должен дать вам желаемый результат.

 curl -XGET 'http://localhost:9200/twitter/_search?q=filename:text'
  

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

1. Анализатор работает. Я добавил пользовательский анализатор, но повторная индексация не помогла.

2. Я создал новый индекс и все еще не повезло… Я определил сопоставление с помощью «filename»: {«type»:»string», «analyzer»:»my_analyzer»} — но безрезультатно. Если я вызываю localhost:9200/_analyze для нового индекса в сравнении с новым анализатором, строка разбивается идеально. Я думаю, я все еще чего-то не понимаю.

3. Я обновил свой ответ. Дайте мне знать, если это не сработает

4. спасибо, что нашли время! Я со всем разобрался. Я добавил новый анализатор в analysis.analyzers.default и добавил фильтр нижнего регистра. Теперь это применяется как анализатор поиска и индекса, и все работает так, как должно.

5. @m_c я в той же лодке и не могу разобраться в этой части: «Я добавил новый анализатор в analysis.analyzers.default и добавил фильтр нижнего регистра»