Как найти любовь или приключения с помощью crate.io и kibana
Про результативность, качество и КПД сайтов знакомств можно спорить, можно искать 101 повод чем лучше в клубе/баре/_дополнить_варианты_/парке искать знакомства. То что еще лет десять-пятнадцать назад вызывало смех — теперь мейнстрим. Так не проще ли попытаться использовать еще одну возможность для поиска и общения в интернет с переходом к знакомству в жизни…
Гиковский вариант технологии поиска, скринкаст приложения под катом. В конце статьи ссылка на архив с работающим приложением под Apache License v2.0 и небольшим набором данных для примера.
Звучит приободряюще, не правда ли?! Реальность несколько сложнее: армии ботов и фейк аккаунтов, работниц древнейшей профессии, попытки сервисами знакомств выжать максимум денег с минимумом результата и даже воры в поисках добычи. Еще интереснее? Не все так грустно и при правильном подходе игра стоит свеч!
Обещаный скринкаст приложения:[embedded content]
Рассмотрим програмную часть для поиска. Делим задачу на две части, как с рисованием совы:
Первая часть — рисуем овал. Для нас это найти, собрать и структурировать данные для дальнейшего поиска. Любой язык программирования с библиотекой html клиента, с регулярными выражениями или работой с DOM/xPath. Для меня эта часть не была проблемой, как разработчика с солидным опытом в интеграции ИТ систем и разработчика распределенного поискового робота для поискового стартапа Visuvi. Если вы считаете, что эта тема интересна, выскажитесь в голосовании за новую тему статьи. Вторая часть — дорисовываем оставшуюся часть совы. Это как сохранить данные в хранилищее информации, проиндексировать их и написать фронтэнд для поиска и просмотра данных. На помощь нам спешит crate.io — это набор плагинов для хранения двоичных данных в файловой системе и выполнения распределенных SQL запросов с помощью возможностей, которые уже есть в поисковом сервере elasticsearch. В двух словах это NoSQL shared nothing база в основе и facebook Presto SQL парсер и планировщик надстройкой над ней. Распределенное решение из мира big data, которое мы будем использовать пока в виде одного процесса на одном компьютере.
Почему crate.io? Нам нужно где-то хранить фото и при этом нужен Elasticsearch, да и SQL может пригодиться для статистики и отчетов в будущем. Успокою вас и в этот раз обойдемся без энтерпрайза, hibernate и JPA). Как увидете, работать crate не сложнее, чем с реляционной базой.
Kibana — HTML5 приложение, позволяющее визуализировать данные из elasticsearch, работать с временными рядами, фильтровать данные, сохранять параметры поиска в виде дашбордов.
Как это может помочь в поисках?! Минимум программирования и максимум результата.Работать с crate.io можно из Python, Ruby, PHP, Java — jdbc type 4 драйвера. Но мне удобнее было включить REST API elasticsearch, который зачем-то скрывают в crate и буду работать через него.
В файле config/crate.yml добавляем параметрыes.api.enabled: trueudc.enabled: false
Второй параметр отключает отчеты об использовании crate.io, отправляемые по UDP на сервер проекта и я сразу же удалил двоичные файлы из библиотеки мониторинга sigar, чтобы не смущать ваш антивирус.
В таком виде «ящик» становится дружелюбным для работы через elasticsearch REST и с помощью spring data elasticsearch.
Для запуска сервера обязательно нужна java jre версии 7 или старше.Запускаю проект bin/crate (в случае с windows нужен файл bin\crate.bat)
С помощью утилиты коммандной строки crash или веб консоли
http://localhost:4200/_plugin/crate-admin/#/console создаю хранилище для фотографий с названием images. bin/crash -c «create blob table images clustered into 7 shards with (number_of_replicas=0)» ±----------------------±----------±--------±----------±--------+ | server_url | node_name | version | connected | message | ±----------------------±----------±--------±----------±--------+ | http://127.0.0.1:4200 | Brigade | 0.45.3 | TRUE | OK | ±----------------------±----------±--------±----------±--------+ CONNECT OK CREATE OK (1.104 sec) Elasticsearch не требует чтобы мы определяли формат данных. В таком решении дьявол кроется в деталях, это скорее тема для обсуждения в комментариях к статье. Я все же укажу типы данных явно с помощью Mapping API, чтобы не было проблем с поиском и отображением в kibana.
Типы данных { «info»: { «mappings»: { «default»: { «properties»: { «accommodation»: { «type»: «string», «index»: «not_analyzed» }, «age»: { «type»: «long» }, «build»: { «type»: «string», «index»: «not_analyzed» }, «drinkingHabits»: { «type»: «string», «index»: «not_analyzed» }, «education»: { «type»: «string», «index»: «not_analyzed» }, «ethnicity»: { «type»: «string», «index»: «not_analyzed» }, «first»: { «type»: «date», «format»: «basic_date_time» }, «height»: { «type»: «long» }, «images»: { «type»: «string» }, «info»: { «properties»: { »: { «type»: «string» }, «Вес»: { «type»: «string» }, «Внешность»: { «type»: «string» }, «Дети»: { «type»: «string» }, «Знание языков»: { «type»: «string» }, «Кого я хочу найти»: { «type»: «string» }, «Материальное положение»: { «type»: «string» }, «Образование»: { «type»: «string» }, «Ориентация»: { «type»: «string» }, «Отношение к алкоголю»: { «type»: «string» }, «Отношение к курению»: { «type»: «string» }, «Отношения»: { «type»: «string» }, «Познакомлюсь»: { «type»: «string» }, «Проживание»: { «type»: «string» }, «Рост»: { «type»: «string» }, «Телосложение»: { «type»: «string» } } }, «kids»: { «type»: «string», «index»: «not_analyzed» }, «last»: { «type»: «date», «format»: «basic_date_time» }, «login»: { «type»: «string» }, «mainImage»: { «type»: «string», «index»: «not_analyzed» }, «message»: { «type»: «string» }, «readableLogin»: { «type»: «boolean» }, «realName»: { «type»: «string» }, «relationship»: { «type»: «string», «index»: «not_analyzed» }, «replyRate»: { «type»: «long» }, «searchingFor»: { «type»: «string» }, «self»: { «properties»: { «В друзьях я больше всего ценю»: { «type»: «string» }, «В женщинах я особенно ценю»: { «type»: «string» }, «В жизни я ставлю перед собой цель»: { «type»: «string» }, «В мужчинах я особенно ценю»: { «type»: «string» }, «Есть ли у меня домашние животные»: { «type»: «string» }, «Из всех известных людей я хотела бы быть»: { «type»: «string» }, «Как долго я смогу прожить без общения»: { «type»: «string» }, «Место, где я бы хотела жить»: { «type»: «string» }, «Мое любимое блюдо»: { «type»: «string» }, «Мое образование»: { «type»: «string» }, «Мое свободное время я хотела бы провести так»: { «type»: «string» }, «Мои любимые литературные герои»: { «type»: «string» }, «Мои любимые музыкальные исполнители»: { «type»: «string» }, «Мои любимые писатели»: { «type»: «string» }, «Мои любимые фильмы»: { «type»: «string» }, «Мои любимые художники»: { «type»: «string» }, «Мой девиз»: { «type»: «string» }, «Мой любимый город»: { «type»: «string» }, «Наивысшее счастье для меня»: { «type»: «string» }, «Самое поразительное открытие для меня»: { «type»: «string» }, «Самой привлекательной чертой своего характера я считаю»: { «type»: «string» }, «Самый ценный совет, который я получила в жизни»: { «type»: «string» }, «Хотела бы я иметь детей»: { «type»: «string» }, «Я больше всего горжусь этим достижением»: { «type»: «string» }, «Я мечтаю о работе»: { «type»: «string» } } }, «smoker»: { «type»: «string», «index»: «not_analyzed» }, «updated»: { «type»: «date», «format»: «basic_date_time» }, «viewed»: { «type»: «long» }, «weight»: { «type»: «long» } } } } } } Запускаем скрипт, который выкачивает html страницы с сайтов, парсит html и извлекает нужные нам данные и сохраняет с помощью REST API/ elasticsearch java client.Обязательно загружаю json с index type = «default», чтобы можно было выполнять SQL запросы.
Пример одного из json документов. cr> select count (*) from info; ±---------+ | count (*) | ±---------+ | 291 | ±---------+ SELECT 1 row in set (0.030 sec) Какой средний возраст в данных из примера?
cr> select avg (age) from info; ±--------------+ | avg (age) | ±--------------+ | 24.7275862069 | ±--------------+ SELECT 1 row in set (0.038 sec) Этот же скрипт скачивает изображения, считает sha1 дайджест и делает http PUT для каждой фотографии в crate.io:
«http://127.0.0.1:4200/_blobs/images/»+fileDigest Можем проверить, что появились записи в blob.images:
cr> select count (*) from blob.images; ±---------+ | count (*) | ±---------+ | 2813 | ±---------+ SELECT 1 row in set (0.029 sec) Отлично, данные в базе!
Скачиваю архив с kibana и распаковываю в директорию plugins/kibana/_site. При перезапуске сервер найдет фронтэнд как плагин site.
В plugins/kibana/_site/config.js указываем адрес к REST API Elasticserch
elasticsearch: «http://»+window.location.host, Все изменения в kibana — незначительные, скорее хаки. По правильному надо было бы сделать свой компонент с возможностью конфигурирования.
Этот фрагмент angularJS шаблона выводит селектор оценки для поля _id в основоной таблице и фотографию, при видимом поле mainImage.
plugins/kibana/_site/app/panels/table/module.html
Код отображение фото в таблице, голосование за оценку
Код отображения всех фотографий
plugins/kibana/_site/index.html
Обновление оценки в json документе, запрос на сервер function postESUpdate (index, type, id, rate){ $.ajax ({ type: «POST», url: «http://»+window.location.host+»/»+index+»/»+type+»/»+id+»/_update», data: '{«doc»:{«rate»:'+rate+'}}' }).done (function (){//alert («success» }).fail (function (){alert («error»)}); } Это вызов elasticsearch Update API для обновления поля документа rate.На этом программирование заканчивается. Дальше только веб интерфейс!
Кратко про создание фильтров вы уже посмотрели в скринкасте в начале статьи.Там же показано как выбрать поддиапазон времени на гистограмме или с помощью timepicker. Все ваши фильтры и настройки можно сохранить в виде дашборда в kibana и загрузить когда нужно по имени.
За рамками этой статьи остались поиск по регулярным выражениям, безопасность сервиса, мониторинг и администрирования crate.io, SQL запросы через jdbc или клиентов для вашего языка программирования.
Повторюсь, что для запуска проекта необходима jvm 7 или старше.
Приложение, с данными для примера, вы можете скачать c дропбокса (234MB tar.gz), распаковать и запустить в *nix командой: bin/crateили windows: bin\crate.bat
Откройте готовый дашборд в браузере:
http://localhost:4200 /_plugin/kibana/#/dashboard/elasticsearch/When%20first%20photo%20was%20uploadedЖелаю удачи с crate.io/kibana и в реальных знакомствах!!!