2015-04-11 3 views
1

Я поддерживаю многолетние действия пользователя, включая просмотр, получение данных. Каждая запись в browse/purchase - это json-объект: {item_id: id1, item_name, name1, category: c1, brand: b1, event_time: t1}.Конструкция индекса Elasticsearch

Я хотел бы составлять различные запросы, такие как получение всех клиентов, которые просматривали элемент A, и/или приобретенный элемент B в интервале времени t1-t2. Есть десятки миллионов клиентов.

Моего текущий дизайна является использование вложенного объекта для каждого клиента:

customer1: 
     customer_id,id1, 
     name: name1, 
     country: US, 
     browse: [{browseentry1_json},{browseentry2_json},...], 
     purchase: [{purchase entry1_json},{purchase entry2_json},...] 

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

Другой дизайн - использовать структуру родителя/ребенка. Тип: пользователь является родителем типа просмотра и покупки. тип просмотра будет содержать каждую запись для просмотра. Хотя удаление старых данных проще с удалением по запросу, для вышеуказанного запроса мне придется делать несколько запросов и/или has_child, и это будет намного менее результативным. Фактически, изначально я использовал родительскую/дочернюю структуру, но время запроса казалось очень длинным. Я, таким образом, отказался и попытался переключиться на вложенный объект.

Я также думаю об использовании вложенного объекта, но разбиваю данные на разные индексы (например, ежемесячный индекс), чтобы я мог легко устаревать старые данные. Проблема с этим подходом заключается в том, что мне приходится запрашивать данные из этих нескольких индексов, и для этого нужно создать агрегацию для получения отдельных пользователей, которые, как я полагаю, будут намного медленнее. (Havn't еще пытался). Одним из требований этого проекта является возможность подсчета запросов в приемлемые временные рамки (например, секунды), и я боюсь, что такой подход может быть неприемлем.

ES-кластер представляет собой 7 машин, каждый из 8 ядер и 32 Гб памяти. Любые предложения?

Заранее благодарен! Chen

ответ

0

Вместо создания индекса клиентов я бы создал индексы «индексирования» и индексы «Покупки», разделенные интервалом времени (EG: Monthly, как вы упомянули в своем последнем абзаце). В каждой структуре я бы добавил поля клиента. Теперь вы сталкиваетесь с двумя различными подходами: 1. Вы можете добавить только ссылку на клиента (например, id) и сделать другой запрос, чтобы получить его данные. 2. Если у вас нет проблемы с хранением, вы можете хранить все данные клиента в каждой структуре.

Если этого недостаточно для производительности, вы можете объединить его с «маршрутизацией» и сохранить все данные конкретного пользователя на одном и том же осколке. и Elasticsearch не нужно будет получать данные между осколками (вы можете смотреть this video где Шей Benon объясняет о «потоке данных пользователя»)

Нив

+0

Это самый естественный способ мышления. Но как я могу сделать простые «и» кросс-индексы запросов типа «кто просматривал элемент А и приобрел элемент Б»? – user648922

+0

вы можете просто использовать запятые между индексами и отображениями. Кстати, я ошибочно написал разные индексы, но вы можете поместить свои типы («просмотр», «покупка») в виде разных сопоставлений. – nivpenso

Смежные вопросы