Общее требование
Частью системы, над которой я сейчас работаю, является обработка необработанных данных. Данные, отправляемые с нескольких клиентских устройств (устройств Android / Iphone и т. Д.) ~ 100 000 запросов в день
Необработанные данные должны быть собраны и готовы для последующего использования. Он должен быть доступен для поиска и агрегировать для расчетов.
У меня было мало опыта с Solr, но на этот раз я хотел попробовать ElasticSearch (ES). Я прочитал об ES из кластера и возможностей шардов, поэтому я попробовал.
ES
Установка проста и быстра. ES поставляется с удобной панелью пользовательского интерфейса (Marvel) и инструментом командной строки для выполнения запросов.
После игры с фреймворком я создал свои первые типы Index и Mapping (MyIndex, MyType).
В тот момент я не знал, как именно будут структурированы мои данные, поэтому я пошел в «запрос всех полей». Это означает, что при поиске одного входа механизм ES будет проходить через все документы и искать в поле каждого документа. Соответствующие документы вернутся.
Мы можем достичь этого, используя поле _all. Это поле включает в себя сглаженный текст одного или нескольких других полей в индексируемом документе. Поле заполняется по умолчанию (если включено).
Запрос довольно прост:
|
1
2
3
4
5
6
|
GET /_search{ "match": { "_all": "Android Galaxy S5 device" }} |
Панель инструментов ES также поставляется с инструментом под названием Sense. С помощью этого инструмента вы можете индексировать и выполнять запросы прямо в ES без использования клиента (это хорошо для тестирования и разработки).
Я предлагаю вам бросить отображение, анализ, повышение, псевдонимы и т.д …
NodeJS
Поэтому после игры с ES я решил написать слой на стороне сервера, который будет моим фасадом ES.
Я намеревался написать простой клиент с единственной строкой поиска, который будет отправлять запросы к ES через уровень сервера и отображать результаты на экране.
ES работает с Json в качестве входа и выхода. Я подумал об использовании JavaScript, который работает комфортно с JSON.
Nodejs — это уровень на стороне сервера, также использующий синтаксис JS. Вот почему JavaScript делает Node идеальным языком для взаимодействия с ElasticSearch. Копать это?
Я взял реализацию клиента ES (asticsearchclient) для NodeJS и после кодирования завершил интеграцию между узлом и ES. Вот пример кода со стороны узла для запроса ES:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
var index = "myindex";var type = "mytype";ElasticSearchClient = require('elasticsearchclient');var Q = require('q');var serverOptions = { host: 'localhost', port: 9200};var elasticSearchClient = new ElasticSearchClient(serverOptions);function performSearch(termToSearch) { var deferred = Q.defer(); console.log("Request handler 'search' was called."); var qryObj = { "query" : { "term" : { "name":termToSearch } } }; elasticSearchClient.search(index, type, qryObj). on('data', function (data) { // console.log(data) deferred.resolve(JSON.parse(data)); }) .on('error', function (err) { console.log(err); return deferred.resolve(err); }) .exec(); return deferred.promise;}exports.performSearch = performSearch; |
NodeJS является однопоточным, который реализован с помощью обработчика событий. Поэтому «тяжелая» логика должна выполняться асинхронно. Я использую Q в моем коде.
Q — это библиотека для создания и составления асинхронных обещаний в JavaScript.
Таким образом, я могу «освободить» зацикливатель событий и создать асинхронные запросы к моему механизму ES и получать чистые обратные вызовы через уровни кода, используя Q.
Через некоторое время я обнаружил необходимость иметь обширный API. Я использовал ExpressJS для этой цели.
ExpressJS
Я хотел, чтобы инфраструктура MVC обеспечивала уровень, подобный rest-api, который будет обрабатывать все запросы API на моей стороне сервера (NodjeJS).
Я пошел в ExpressJS, который, по-видимому, является самой популярной веб-инфраструктурой для Node.js среди веб-разработчиков (мы, как опытные разработчики открытого кода, знаем, что сообщество имеет значение!).
Я одержим структурой проекта. Я из мира Java, и иногда проекты javascript кажутся мне джунглями. Я искал популярный и традиционный способ структурировать свой проект NodeJS вместе с ExpressJS.
Поэтому, поиграв с фреймворком, я обнаружил, что с Yeoman и generator-express вы быстро генерируете структуру проекта Nodejs, включая все необходимые библиотеки expressJS, чтобы вы могли работать.
Дерево моего проекта выглядело так:
Пример контроллера ExpressJS:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
var express = require('express');var router = express.Router();var esService = require('../services/esService');var Q = require('q');router.get("/search", function (req, res) { var termToSearch = req.query.termToSearch; console.log("termToSearch=" + termToSearch); Q(esService.performSearch(termToSearch) ).then(function (data) { res.send("Session: %j", data); });}) |
Контроллер вызывает метод perfomSearch с использованием esService и асинхронно возвращает результаты обратно клиенту JS, используя обещания.
Это код клиента JS, который отображает результаты в элемент HTML:
* Я использовал библиотеку prettyPrint, чтобы красиво распечатать результат json на экране:
|
1
2
3
4
5
6
7
8
9
|
function handleClick() { var inputParam = document.querySelector("#myinput").value; console.log(responseText); $("#resultlist").append(prettyPrint(responseText)); }); return false;} |
Идан.
| Ссылка: | Мой опыт использования ElasticSearch NodeJS и ExpressJS от нашего партнера по JCG Идана Фридмана в блоге IdanFridman.com . |

