Pull to refresh

Comments 19

Эластик — отличная штука. Его гибкость — это и главный плюс, и главный минус (по началу, потом этот минус пропадает)
в эластике есть два механизма: query и filter. Они работают по разному и предназначены для разных вещей.
Разные фильтры работают по разному, есть filter и query, которые на первый взгляд выполняют одно и то же действие, но реализуют они это действие совершенно разными подходами. Если в двух словах, то query — медленный, filter — быстрый.
rule of thumb: нужно сначала максимально срезать выборку фильтрами и потом по результатам прокатывать query.
Для того же range есть фильтры.
Вот этот запрос
{ "match_phrase": { "content.text": "иванов иван"} }

фактически обозначает поиск документов, которые содержат слово «иванов» и слово «иван» в поле context.text.
Что это означает? Это означает, что есть индекс всех токенов (условно слов) из поля context.text для всех документов маппинга, и нужно найти пересечение двух запросов типа token=«иванов» и token=«иван». Это вроде как уже давно не мега задача для индексов.
А индекс по полю context.text эластик сам сформирует или надо отдельно в конфиге задавать?
в принципе можно маппинг вообще не определять. Эластик сам его определит, как сумеет, на основании первого значения, которое попадется в этом поле. Но потом можно огрести по полной, т.к. маппинг поля менять нельзя. Предположим у вас есть поле, в котором будут храниться хеши. Но так случайно вышло, что первым значением в этом поле, попавшим в индекс, оказался хеш, состоящий только из цифр. Эластик интерпретирует его как число. В дальнейшем, когда вы попытаетесь проиндексировать хеш, который будет содержать буквы, он будет ругаться, что значения не соответствует маппингу.
Про один только маппинг можно написать статью, которая будет в несколько раз больше данной. Через него в том числе определяется как текст будет разбиваться на токены, с помощью которых будет производиться полнотекстовый поиск. Более того, можно задать разные анализаторы для индексации и для поиска. Можно даже настроить несколько способов токенизации для одного и того же поля. А в дальнейшем проводить поиск с указанием нужной токенизации.
Если вы планируете, делать что-то действительно серьезное, то лучше не расчитывать на автоматический маппинг, не взлетит) А если взлетит, то не высоко
Мда.
А ведь одно время я почти убедил себя, что понимаю, чем query отличается от search…
Похоже, снова забыл. ;-(

Про автомаппинг я, пожалуй, смогу сделать вид, что понял. А вот про индексы — не очень. Грубо говоря, эластик автоматически формирует индексы по всем определённым в маппинге полям и наполняет эти индексы токенами, полученными после разбора строк в этих полях?
этим всем занимается lucene, но да, под каждое поле создается отдельный индекс. Про токены имеет смысл говорить только для строковых типов, все остальные не токенизируются

Вы упустили главную деталь статьи — документы в ES большого размера. Если ваши документы небольшие то искать по ним с помощью ES очень легко, если же поле content.text размером 150 Мб вот тут и начинаются оптимизации

как размер поля документа влияет на скорость поиска? Он же не по исходному тексту ищет, а по индексу, составленному из токенов, которые получились после прогона анализаторов через этот текст.
иными словами статья получается такая:
ребята, смотрите, какой классный набор «молоток и микроскоп». Перед нами возникла задача забивать гвозди. Сначала мы попробовали забивать гвозди окуляром, но вышло плохо, стекла все время бьются. После этого мы немного изучили микроскоп, и пришли к выводу, что лучше всего забивать гвозди основанием микроскопа. В результате все гвозди были успешно забиты.
Ну серьезно

Я считаю что вы не правы. Увеличение скорости поиска в 1100 раз это не "экономия на спичках" — это описание решения конкретной задачи

Ну это я сразу понял, что вы так считаете) Я имел в виду то, что если исходить из того, что полный набор возможностей оптимизаций вашей выборки составляет 100%, то вы тут описываете ну не больше 10%.

Уважаемый pavlick. Предлагаю вам вместо того, чтобы критиковать наш подход, просто предложить ваше решение проблемы. Потому что пока от вас были только комментарии, которые показывают только то, что вы или невнимательно прочитали статью, или просто не разбираетесь в теме.
С уважением.

Уважаемый fpd4444. Во-первых, спасибо за вашу квалифицированную оценку моих навыков, ваша оценка для меня очень важна. Во-вторых, обычно правильная постановка вопроса дает как минимум половину ответа на вопрос. Совсем глобально ваш вопрос понятен — как ускорить работу поисковых запросов. Какие-то аспекты я уже упомянул. Какие-то аспекты вашей задачи вообще не упомянуты, хотя они важны в вопросе скорости выполнения запросов. Могу предложить вам двигаться в таком направлении:
— как устроен индекс ES (шарды, сегменты, собственно сам Lucene)
— как выполняются запросы в индексе ES
Когда с частью, за которую отвечает именно ES разобрались, можно приступать к оптимизации уже на уровне базовых индексов lucene.
— в чем разница между query и filter
— для чего стоит использвать каждый из них
— кто из них и как связан со скорингом
— выяснить, как вы в своей задаче используете скоринг
— подходит ли вам дефолтный скоринг и нужен ли он вам вообще

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

Потом можете посмотреть, а что же сейчас из себя представляет ваш индекс, может быть, он в настолько плачевном состоянии, что надо изменить «какие-то» настройки самого индекса. (Тут вдруг может оказаться, что вы могли существенно сократить время выполнения ваших запросов, даже не трогая мапинг и сам запрос).

Опять-таки, вы упомянули, что используете SATA, хоть и в десятке. Дефолтные настройки ES подразумевают использование SSD. Но не имея вообще никакой информации о том, под какой нагрузкой вы получили изначальные цифры, нельзя сказать, успели вы уже испытать на себе проблему с этими настройками, под которые SATA не очень подходят.

Желаю вам удачи в освоении ES :)

Спасибо. Но я его уже давно освоил.

Ну… тогда могу только предположить, что этот цикл вы собрались растянуть на пару сотен постов )
Стоить заметить, что для поля content.text указывать store: true нужно только если мы хотим чтобы работал highlighting, или если мы хотим получать это поле в ответе от elastic. Если это не требуется, то мы можем указать store: false, что заметно снизит размер индекса.
А вслучае если нам не надо получать от elastic ничего кроме id документа (например сам документ можно достать из другой базы) то можно указать в маппинге _source: {enabled: false }, что дополнительно сохратит размер индекса и повысит производительность, то же самое можно сделать и со специальным полем _all, так как оно обычно не нужно _all: {enabled: false}

Полностью согласен с вами. Нам нужны highlights поэтому поставили store: true

Sign up to leave a comment.

Articles