# Реляционные паттерны MapReduce. Лекция 7 ## Выборка ![](https://i.imgur.com/bvOsf3O.png) Пусть Map принимает кортеж t, если этот кортеж удовлетворяет заданному условию, то продвигается дальше в контекст. Реализация выборки обходится без Reduce. ## Проекция ![](https://i.imgur.com/RmYz33h.png) Здесь Map также принимает кортеж t, но оставляет в нем только нужные элементы, формируя кортеж g, который продвигает дальше в контекст в качестве ключа, в качестве значений используются нулевые ссылки. ![](https://i.imgur.com/pvwkb6j.png) Избыточные дубликаты кортежей можно исключить, включив Reduce в конвейер вычислений. Reduce получит итератор по списку из нулевых ссылок для отдельного ключа, их количество соответсвует количеству дубликатов. ## Объединение ![](https://i.imgur.com/K4s0qUV.png) На вход Map передаются кортежи из 2-х множеств: A и B. Всякий кортеж просто продвигается дальше в контекст в качестве ключа, в качестве значения выступает нулевая ссылка. ![](https://i.imgur.com/rdD480F.png) Reduce получит итератор по списку из нулевых ссылок для отдельного ключа, их количество будет равно либо 1 (когда кортеж встретился только в одном множестве), либо 2 (когда в обоих). Поскольку дубликаты здесь не нужны, ключ продвигается дальшге в контекст вместе с нулевой ссылкой в качестве значения. ## Пересечение ![](https://i.imgur.com/AEXIMh3.png) На вход Map передаются кортежи из 2-х множеств: A и B. Всякий кортеж просто продвигается дальше в контекст в качестве ключа, в качестве значения выступает нулевая ссылка. ![](https://i.imgur.com/acavPK3.png) В функции Reduce производится проверка, допускающая вывод только тех кортежей, которые встретились сразу в обоих множествах. Это легко проверить по списку нулевых ссылок, он должен содержатьт 2 элемента. ## Разность В данном случае нам важно из какого множества пришел кортеж. ![](https://i.imgur.com/ZdiZn2Q.png) На вход Map передаются кортежи из 2-х множеств: A и B. Всякий кортеж просто продвигается дальше в контекст в качестве ключа, в качестве значения выступает имя множества, из которого пришел кортеж. ![](https://i.imgur.com/b2rDjhz.png) Reduce проверяет, что кортеж присутсвует только в 1 множестве, делает он это по длине итерируемого списка. Но требуется и дополнительная проверка: это должно быть именно множество А, только в этом случае кортеж формирует ответ. ## Симметрическая разность ![](https://i.imgur.com/xhG4FHK.png) На вход Map передаются кортежи из 2-х множеств: A и B. Всякий кортеж просто продвигается дальше в контекст в качестве ключа, в качестве значения выступает имя множества, из которого пришел кортеж. ![](https://i.imgur.com/ZJjeOeo.png) В данном случае у Reduce нет проверки множества, поскольку все кортежи, входящие только одно из множеств формируют ответ. ## Агрегирование и группировка данных ![](https://i.imgur.com/YGsSzYK.png) Map принимает на вход кортеж, поле, по которому предполагается группировка - **GroupBy**, поле, по которму предполагается агрегирование - **AggregateBy**. Map записывает в контекст пару ключ-значение, где в качестве ключа используется **GroupBy**, а в качестве значения выступает **AggregateBy**. ✓ Группировка по нужному полю произойдёт автоматически, в фазе shuffle and sort. ![](https://i.imgur.com/4hUgVjc.png) ✓ Агрегацию значений для отдельного ключа легко выполнить уже в Reduce. В контекст записывается пара ключ-значение, где **GroupBy** остается в качестве ключа, а в качестве значения выступает результат применения агрегирующей функции к итерируемому списку значений **AggregateBy**. ## Repartition Join (Reduce Join, Sort-Merge Join): Map ![](https://i.imgur.com/m1ZFmdn.png) Применяется, когда необходимо объединить два множества R и L по ключу k. Map получает на вход кортежи из каждого множества, и пишет в контекст пары ключ-значение: 1. **Ключ** - ключевое поле k, по которому предполагается соединение. В контексте реляционных баз данных может рассматриваться как первичный ключ или как внешний ключ. 2. **Значение** - информационные поля [ v1, v2, ... ], промаркированные тегом, определяющим множество, из которого пришло значение. ## Repartition Join (Reduce Join, Sort-Merge Join): Reduce ![](https://i.imgur.com/Q74eyAv.png) Применяется, когда необходимо объединить два множества R и L по ключу k. Reduce получает на вход группу значений для одного ключа, и размещает их по двум корзинам, соответствующим каждому входному множеству. Это легко реализовать, создав ассоциативный массив h, который будет содержать всего 2 элемента, **его ключами будут имена входных множеств**, а **значениями списки, моделирующие соответствующие корзины**. При итерировании по списку маркированных кортежей их полезная нагрузка помещается в корзин, название которой определено тэгом. После этого Reduce проходит по обеим корзинам и генерирует объединения значений из двух множеств с общим ключом. ## Repartition Join (Reduce Join, Sort-Merge Join): Особенности **Достоинства**: универсальность. **Недостатки**: 1. Map отправляет на выход все данные, даже для тех ключей, которые есть только в одном множестве. 2. Reduce должен хранить все значения для одного ключа впамяти. 3. Нужно самостоятельно управлять памятью в случае, если данные в нее не помещаются. ## Replicated Join (Map Join, Hash Join) Этот подход эффективен, когда требуется объединить два множества разных размеров – маленькое и большое. Например, список пользователей с логом их активности. ![](https://i.imgur.com/TRdbc64.png) Для этого можно: 1. Использовать хеш-таблицу, куда загружаются все элементы маленького множества, сгруппированные по ключу k; 2. Осуществить проход по элементам большого множества с помощью задач Map, выполняя поисковый запрос к этой хеш-таблице для каждого входного кортежа. Сформировать хэш-таблицу можно при помощи ассоциативного массива h в момент реализации задачи Map, поскольку эта таблица будет применяться неоднократно при обработке входного сплита. **Ключи h** будут определяться значениями ключевого поля k, по которому предполагается соединение. **Значения h** будут определяться списками, содержащими полезную нагрузку в виде кортежей с информационными полями. Функция Map принимает на вход кортеж из большого множества, **поле k**, по которому предполагается соединение, выделено **в качестве ключа**, а **полезная нагрузка** с информационными полями **в виде значения**.