#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 и добавил фильтр нижнего регистра»