Elasticsearch несколько анализаторов для одного поля

я храню различные виды документов в одном индексе со строгим предопределенным отображением. Все они имеют некоторое поле (скажем, "тело"), но я бы хотел, чтобы они были проанализированы немного по-разному при индексировании (например, для использования разных фильтров токенов для определенных документов) и обрабатывались одинаково во время поиска. Насколько мне известно, анализаторы не могут быть указаны для каждого документа.

что я также считал использовать:

  1. поля объектов с различным анализом подполя для видов документов, поэтому каждый документ имеет только одно заполненное подполе (например, " тело.почта", "тело.формат HTML.)" Проблема в том, что я не мог искать по всему полю "тело", которое просматривало бы все его подполя (чтобы не сломать существующее приложение).
  2. новая реинкарнация мульти-полей (иметь поле " тело "с общим анализатором и custonly анализируемой" почтой"," html " и т. д. внутри него.) Hovewer, я не уверен, можно ли использовать их напрямую при индексации и косвенно при поиске (например, для сохранения объекта с {"mail":"smth"} чтобы использовать определенный анализатор индекса, выполните поиск по "query":{"body":"smth"} использовать универсальный анализатор поиска).
  3. чтобы разделить "тело" на несколько полей с различными отображениями, удалите их из _all и set copy_to один

2 ответов


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

             -- body.html          
             -- body.email
body field ---- body.content     --- all searched as "body"
            ...
             -- body.destination
             -- body.whatever
  • первый вариант мульти-месторождения который имеет в виду именно эту цель: иметь одни и те же данные, проанализированные несколькими способами. Проблема в том, что вы не можете искать "body" и ожидать ES для поиска body.html, body.email... Даже если это было бы возможно, вы хотите, чтобы вас искали с помощью разных анализаторов. Опять же, это невозможно. Эта опция требует от вас изменить приложение и поиск для каждого поля в multi_match или query_string.

  • ваш второй вариант - reincarnation of multi-fields - опять не работает, потому что вы не можете ссылаться на body и ES, в фоновом режиме, чтобы соответствовать mail, content etc.

  • третий опция-использование copy_to - не будет работать, потому что копирование в другое поле " X " означает индексирование копируемых данных будет проанализировано с X'анализатор с, и это нарушает ваше требование иметь одни и те же данные, проанализированные по-разному.

  • может быть четвертый вариант -"path": "just_name" С multi_fields - что на первый взгляд должно сработать. Это означает, что вы можете иметь 3 мульти-поля (электронная почта, контент, html), которые все три имеют body суб-поля. Имея "path": "just_name" позволяет искать только на body даже если body является подполем нескольких других полей. Но это невозможно, потому что этот тип мульти-месторождения не будет принимать различные анализаторы для одного и того же body.

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


это говорит, мне интересно увидеть, какие запросы вы используете в своем приложении. Это было бы простое изменение ( да, вам нужно будет изменить свое приложение) из запроса body поле для запроса body.* на multi_match.

и у меня есть другое решение для вас: создайте несколько индексов, один индекс для каждого анализатора вашего body. Например, для mail, content и html вы определяете три индекса:

PUT /multi_fields1
{
  "mappings": {
    "test": {
      "properties": {
        "body": {
          "type": "string",
          "index_analyzer": "whitespace",
          "search_analyzer": "standard"
        }
      }
    }
  }
}
PUT /multi_fields2
{
  "mappings": {
    "test": {
      "properties": {
        "body": {
          "type": "string",
          "index_analyzer": "standard",
          "search_analyzer": "standard"
        }
      }
    }
  }
}
PUT /multi_fields3
{
  "mappings": {
    "test": {
      "properties": {
        "body": {
          "type": "string",
          "index_analyzer": "keyword",
          "search_analyzer": "standard"
        }
      }
    }
  }
}

вы видите, что все они имеют одинаковое type и то же имя поля -body - но разные index_analyzers. Затем вы определяете псевдоним:

POST _aliases
{
  "actions": [
    {"add": {
        "index": "multi_fields1",
        "alias": "multi"}},
    {"add": {
        "index": "multi_fields2",
        "alias": "multi"}},
    {"add": {
        "index": "multi_fields3",
        "alias": "multi"}}
  ]
}

Назовите свой псевдоним так же, как ваш текущий индекс. Приложение не нуждается в изменении, оно будет использовать то же имя для поиска индекса,но это имя будет указывать не на индекс, а на псевдоним, который, в свою очередь, относится к вашим нескольким индексам. Что нужно изменить, так это то, как вы индексируете документы, потому что a html документы должны идти в например, email документ должен быть индекс в multi_fields2 индекс etc.

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


Я думаю, вы можете использовать multi-field. С помощью multi-field вы можете определить анализаторы (индексирование и поиск) для каждого подполя и выполнить поиск по соответствующим полям на основе требований приложений. Вообще, анализатор индекса может быть разницей от поля к полю, этим же для анализатора поиска.

{
  "your_type" : {   
    "properties":{
        "body" : {
            "type" : "string",
            "index" : "analyzed",
            "index_analyzer" : "index_body_analyzer",
            "search_analyzer" : "search_body_analyzer",
            "fields" : {
                "mail" : {
                    "type" : "string",
                    "index" : "analyzed",
                    "index_analyzer" : "index_bodymail_analyzer",
                    "search_analyzer" : "search_bodymail_analyzer"
                },
                "html": {
                    "type" : "string",              
                    "index" : "analyzed",
                    "index_analyzer" : "index_bodyhtml_analyzer",
                    "search_analyzer" : "search_bodyhtml_analyzer"
                }
            }
        }
    }
}