Общее требование
Частью системы, над которой я сейчас работаю, является обработка необработанных данных. Данные, отправляемые с нескольких клиентских устройств (устройств 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 . |