Looking for elasticsearch Answers? Try Ask4KnowledgeBase
Looking for elasticsearch Keywords? Try Ask4Keywords

ElasticsearchРазница между индексами и типами


замечания

Легко видеть type s как таблицу в базе данных SQL, где index - это база данных SQL. Однако это не очень хороший подход к type s.

Все о типах

Фактически, типы - это буквально только поле метаданных, добавленное в каждый документ _type : _type . В приведенных выше примерах создаются два типа: my_type и my_other_type . Это означает, что каждый документ, связанный с типами, имеет дополнительное поле, автоматически определяемое как "_type": "my_type" ; это индексируется с документом, что делает его полем поиска или фильтрации , но оно не влияет на сам исходный документ, поэтому вашему приложению не нужно беспокоиться об этом.

Все типы живут в одном и том же индексе и, следовательно, в тех же коллективных осколках индекса. Даже на уровне диска они живут в одних и тех же файлах. Единственное разделение, создающее второй тип, является логичным. Каждый тип, независимо от того, является он уникальным или нет, должен существовать в сопоставлениях, и все эти сопоставления должны существовать в вашем состоянии кластера. Это поглощает память, и, если каждый тип обновляется динамически, он увеличивает производительность при изменении сопоставлений.

Таким образом, лучше всего определить только один тип, если вам действительно не нужны другие типы. Обычно встречаются сценарии, в которых желательны несколько типов. Например, представьте, что у вас был автомобильный указатель. Возможно, вам будет полезно разбить его несколькими типами:

  • БМВ
  • гнаться
  • Хонда
  • мазда
  • мерседес
  • ниссан
  • Range Rover
  • Тойота
  • ...

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

GET /cars/_search

а также

GET /cars/bmw/_search

Что не очевидно для новых пользователей Elasticsearch, так это то, что вторая форма является специализацией первой формы. Он буквально переписывается:

GET /cars/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term" : {
            "_type": "bmw"
          }
        }
      ]
    }
  }
}

Он просто отфильтровывает любой документ, который не был проиндексирован в поле _type , значение которого было bmw . Поскольку каждый документ индексируется с его типом в качестве поля _type , это служит довольно простым фильтром. Если фактический поиск был предоставлен в любом примере, тогда фильтр будет добавлен к полному поиску, если это необходимо.

Таким образом, если типы идентичны, гораздо лучше поставлять один тип (например, manufacturer в этом примере) и эффективно игнорировать его. Затем в каждом документе явно укажите поле под названием make или другое имя, которое вы предпочитаете, и вручную фильтруйте его, когда вы хотите его ограничить. Это уменьшит размер ваших сопоставлений до 1/n где n - количество отдельных типов. Он добавляет другое поле к каждому документу в пользу упрощенного сопоставления.

В Elasticsearch 1.x и 2.x такое поле должно быть определено как

PUT /cars
{
  "manufacturer": { <1>
    "properties": {
      "make": { <2>
        "type": "string",
        "index": "not_analyzed"
      }
    }
  }
}
  1. Имя произвольное.
  2. Имя произвольное, и оно может совпадать с именем типа, если вы тоже этого хотели.

В Elasticsearch 5.x вышеупомянутое все равно будет работать (оно устарело), ​​но лучший способ - использовать:

PUT /cars
{
  "manufacturer": { <1>
    "properties": {
      "make": { <2>
        "type": "keyword"
      }
    }
  }
}
  1. Имя произвольное.
  2. Имя произвольное, и оно может совпадать с именем типа, если вы тоже этого хотели.

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

Общие вопросы

  • Что делать, если у меня есть два (или более) типа, которые в основном идентичны, но которые имеют несколько уникальных полей для каждого типа?

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

Сказано иначе: редко используемое поле разрежено по индексу независимо от типов . Разделение не приносит пользу - или действительно больно - индекс только потому, что он определен в отдельном типе.

Вы должны просто объединить эти типы и добавить отдельное поле типа.

  • Почему отдельные типы должны точно определять поля точно так же?

Поскольку каждое поле действительно определено только один раз на уровне Lucene, независимо от количества типов. Тот факт, что типы существуют вообще, является особенностью Elasticsearch, и это только логическое разделение.

  • Могу ли я определить отдельные типы с одинаковым полем, определенным по-разному?

Нет. Если вам удастся найти способ сделать это в ES 2.x или новее, тогда вы должны открыть отчет об ошибке . Как отмечалось в предыдущем вопросе, Луцен видит их всех как одно поле, поэтому нет возможности сделать эту работу надлежащим образом.

ES 1.x оставил это как неявное требование, которое позволило пользователям создавать условия, при которых одно отображение осколков в индексе фактически отличалось от другого осколка в том же индексе. Это было фактически условием гонки, и это могло привести к неожиданным проблемам.

Исключения из правила

  • Родительские / дочерние документы требуют использования отдельных типов в одном и том же индексе.
    • Родитель живет одним типом.
    • Ребенок живет в отдельном типе (но каждый ребенок живет в том же осколке, что и его родитель).
  • Чрезвычайно нишевые случаи использования, когда создание тонны индексов нежелательно, а влияние разреженных полей предпочтительнее альтернативы.
    • Например, плагин мониторинга Elasticsearch, Marvel (1.x и 2.x) или X-Pack Monitoring (5.x +), контролирует сам Elasticsearch для изменений в кластере, узлах, индексах, конкретных индексах (уровне индекса), и даже осколки. Он может создавать 5 + индексов каждый день, чтобы изолировать те документы, которые имеют уникальные сопоставления, или может пойти против лучших практик, чтобы уменьшить нагрузку на кластер, разделив индекс (обратите внимание: количество определенных сопоставлений фактически одинаково, но количество созданных индексов уменьшается от n до 1).
    • Это расширенный сценарий, но вы должны учитывать общие определения полей для разных типов!

Разница между индексами и типами Связанные примеры