ElasticSearch — поиск с дефисами

Эластичный поиск 1.6

Я хочу проиндексировать текст, содержащий дефисы, например, U-12, U-17, WU-12, футболка... и иметь возможность использовать запрос «Строка простого запроса» для поиска по ним.

Образец данных (упрощенный):

{"title":"U-12 Soccer",
 "comment": "the t-shirts are dirty"}

Поскольку вопросов о дефисах уже довольно много, я уже попробовал следующее решение:

Используйте фильтр Char: ElasticSearch — поиск с дефисами в имени.

Итак, я пошел на это сопоставление:

{
  "settings":{
    "analysis":{
      "char_filter":{
        "myHyphenRemoval":{
          "type":"mapping",
          "mappings":[
            "-=>"
          ]
        }
      },
      "analyzer":{
        "default":{
          "type":"custom",
          "char_filter":  [ "myHyphenRemoval" ],
          "tokenizer":"standard",
          "filter":[
            "standard",
            "lowercase"
          ]
        }
      }
    }
  },
  "mappings":{
    "test":{
      "properties":{
        "title":{
          "type":"string"
        },
        "comment":{
          "type":"string"
        }
      }
    }
  }
}

Поиск осуществляется по следующему запросу:

{"_source":true,
  "query":{
    "simple_query_string":{
      "query":"<Text>",
      "default_operator":"AND"
    }
  }
}
  1. Что работает:

    "U-12", "U*", "t*", "ts*"

  2. Что не сработало:

    "U-*", "u-1*", "t-*", "t-sh*", ...

Итак, кажется, что фильтр char не выполняется в строках поиска? Что я мог сделать, чтобы это сработало?


person Roeland Van Heddegem    schedule 18.06.2015    source источник


Ответы (3)


Ответ действительно прост:

Цитата Игоря Мотова: Настройка стандартного токенизатора

По умолчанию запрос simple_query_string не анализирует слова с подстановочными знаками. В результате он ищет все токены, начинающиеся с i-ma. Слово i-mac не соответствует этому запросу, так как при анализе оно разбивается на две лексемы i и mac, и ни одна из этих лексем не начинается с i-ma. Чтобы этот запрос нашел i-mac, вам нужно заставить его анализировать подстановочные знаки:

{
  "_source":true,
  "query":{
    "simple_query_string":{
      "query":"u-1*",
      "analyze_wildcard":true,
      "default_operator":"AND"
    }
  }
}
person Roeland Van Heddegem    schedule 18.06.2015

Цитата Игоря Мотова верна, надо добавить "analyze_wildcard":true, для того, чтобы работало с regex. Но важно отметить, что дефис на самом деле обозначает «u-12» в «u» «12», двух отдельных словах.

если важно сохранить оригинал, не используйте Mapping char filter. В противном случае вроде полезно.

Представьте, что у вас есть «m0-77», «m1-77» и «m2-77». Если вы будете искать m*-77, у вас будет ноль совпадений. Однако вы можете заменить «-» (дефис) на И, чтобы соединить два разделенных слова, а затем выполнить поиск m* И 77, который даст вам правильный результат.

вы можете сделать это на клиентском фронте.

В вашей проблеме u-*

{
  "query":{
    "simple_query_string":{
      "query":"u AND 1*",
      "analyze_wildcard":true
    }
  }
}

t-sh*

  {
      "query":{
        "simple_query_string":{
          "query":"t AND sh*",
          "analyze_wildcard":true
        }
      }
    }
person londox    schedule 11.07.2017

Если кто-то все еще ищет простое решение этой проблемы, замените дефис на подчеркивание _ при индексировании данных.

Например, O-000022334 следует индексировать как O_000022334.

При поиске снова замените подчеркивание на дефис при отображении результатов. Таким образом, вы можете искать «O-000022334», и он найдет правильное совпадение.

person Jesal    schedule 17.04.2019
comment
Как насчет того, если в данных уже есть подчеркивание _, а замена на вывод hypen display будет неправильным.. - person Satya Prakash; 22.04.2019
comment
Если исходные данные имеют знак подчеркивания, вам, очевидно, не нужно заменять его дефисом. - person Jesal; 23.04.2019