#elasticsearch #elasticsearch-aggregation
#elasticsearch #elasticsearch-агрегирование
Вопрос:
Недавно я добавил elasticsearch в качестве поисковой системы для проекта, это структурная модель электронной коммерции, и я использую ее для загрузки категорий, производителей и т.д.
Запросы обычно выполняются очень быстро, около 200 мс, что довольно хорошо, учитывая количество продуктов, которые у меня есть, поскольку в некоторых проектах у меня более миллиона продуктов.
Однако в некоторых случаях, например, на простой странице категории, где у меня около 550 тысяч товаров на этой странице категории, запрос занимает около 500 мс, мне интересно, могу ли я оптимизировать его, чтобы он был быстрее.
Пожалуйста, не обращайте внимания на то, что я добавил агрегации и дополнительные фильтры в запрос в зависимости от выбранных клиентом опций, но в целях оптимизации я удалил их, поскольку у меня одинаковая скорость загрузки с ними или без них.
Этот запрос в данном конкретном случае занимает около 500-600 мс
Array
(
[size] => 48
[from] => 0
[sort] => Array
(
[date_upd] => Array
(
[order] => desc
)
)
[query] => Array
(
[bool] => Array
(
[filter] => Array
(
[0] => Array
(
[term] => Array
(
[id_product_categories] => 38231
)
)
)
)
)
)
Структура индекса elasticsearch выглядит следующим образом:
$data = массив (
'settings' =>
array(
'number_of_shards' => 1,
'number_of_replicas' => 0,
'analysis' => $analysis,
'index' => array(
'sort.field' => array('date_add','date_upd', 'reduction_percent','price'),
'sort.order' => array('desc','desc','desc','desc')
)
),
'mappings' => array(
'product' => array(
//'type' => 'product',
'_all' => array( 'enabled' => false),
'properties' => array
(
'id_product' => array(
'type' => 'integer'),
'id_image' =>array(
'type' => 'integer',
'null_value' => 0
),
'id_supplier' => array(
'type' => 'keyword',
'null_value' => 0,
'index' => true,
'eager_global_ordinals' => true
),
'id_manufacturer' => array(
'type' => 'keyword',
'null_value' => 0,
'index' => true,
'eager_global_ordinals' => true
),
'id_color' => array(
'type' => 'keyword',
'null_value' => 0,
'index' => true,
'eager_global_ordinals' => true
),
'rating' => array(
'type' => 'keyword',
'null_value' => 0,
'index' => true,
),
'id_default_category' => array(
'type' => 'integer',
'null_value' => 0
),
'popularity' => array(
'type' => 'integer',
'null_value' => 0
),
'reduction_percent' => array(
'type' => 'integer',
'null_value' => 0,
'index' => true
),
'is_reduced' => array(
'type' => 'boolean'
),
'reference' => array(
'type' => 'keyword',
'null_value' => 0,
'index' => true,
),
'image_cover' => array(
'type' => 'keyword',
'index' => false,
),
'image_title' => array(
'type' => 'keyword',
'index' => false,
),
'product_link_title' => array(
'type' => 'keyword',
'index' => false,
),
'price' => array(
'type' => 'integer',
'null_value' => 0,
'index' => true
),
'old_price' => array(
'type' => 'float',
'null_value' => 0
),
'id_product_categories' => array(
'type' => 'keyword',
'null_value' => 0,
'index' => true,
'eager_global_ordinals' => true
),
'date_add' => array(
'type' => 'date',
'format' => 'yyyy-MM-dd HH:mm:ss',
'index' => true
),
'date_upd' => array(
'type' => 'date',
'format' => 'yyyy-MM-dd HH:mm:ss'
),
'product_name' => array(
'type' => 'text',
"analyzer" => $lang_iso_code .'_analyzer'
),
'product_heading' => array(
'type' => 'keyword',
"index" => false
),
/*
'product_description' => array(
'type' => 'text',
"analyzer" => $lang_iso_code .'_analyzer'
),
*/
'product_color' => array(
'type' => 'text',
"analyzer" => $lang_iso_code .'_analyzer'
),
'product_categories' => array(
'type' => 'text',
"analyzer" => $lang_iso_code .'_analyzer'
),
'product_manufacturer' => array(
'type' => 'text',
),
'product_supplier' => array(
'type' => 'text'
),
'product_link' => array(
'type' => 'keyword',
'index' => false
)
)
)
)
);
Комментарии:
1. Вы уверены, что это время выполнения запроса, а не время выборки данных? Если ваш запрос возвращает 550 тыс. элементов, передача всех данных может занять много времени. Попробуйте ограничить результаты, чтобы подтвердить, так ли это
2. @Alex Я уверен, что это не время выборки, оно возвращает только 48 элементов, у меня размер => 48 в начале запроса, смотрите Пример выше. Всего в запросе 550 тыс. товаров (общее количество просмотров)
3. Кто-нибудь может помочь с этим?
4. На данный момент у меня нет Elastic sever для тестирования. Но просто предположение, расширьте свой
settings
=>'sort.field' => array('date_add','date_upd', 'reduction_percent','price'),
с помощьюid_product_categories
5. Если это ваш фактический запрос (я не вижу части агрегирования).
term
Запрос должен быть действительно быстрым — но вы помещаете его внутрьfilter
, поэтому ES будет его кэшировать. Обычно наличие кэша действительно хорошо, но если он пытается поместиться в ваш самый дорогой запрос … возможно, нет. Вы можете проверить, все ли еще 500 мс, если просто запуститеquery: { term: { [id_product_categories] : { value : "38231" } } }