git clone https://github.com/ria-com/test-project-june-2017
cd test-project-june-2017
npm i
npm test
Необходимо написать модуль, который бы конвертировал обычные строки в запросы к ElasticSearch по заданным правилам. При этом НЕЛЬЗЯ использовать сторонние модули. Можно использовать модули node.js и чистый JavaScript.
Основным критерием для оценки будет прохождение тестов, которые можно запустить командой:
npm test
Дополнительными критериями является качество, чистота и документированность кода.
- Строка является валидной строкой GET-запроса. Это значит, что параметры в ней разделяются при помощи знака
&
- Параметры могут быть массивами, объединяться в группы и еще к ним могут применяться различные действия, например логическое
НЕ
- Результат работы модуля - сериализируемый при помощи метода
JSON.stringify
объект, который после сериализации превратится в валидный запрос к ElasticSearch - Имя параметра
group
зарезервировано для групп параметров (см. "Группы")
Параметр
- набор символов из букв английского алфавита (a-z, и большие в том числе), цифр (0-9), точки ('.') и квадратных скобок ('[' и ']')Суффикс
- часть параметра после точки в концеИндекс
- число внутри квадратных скобокНазвание параметра
- всё, что не вошло в суффикс и индекс
Возьмем самый сложный случай: price[0].gte
, где:
- price - название параметра
- 0 - индекс
- gte - суффикс
Простой вариант: brand.id
, где:
- brand.id - название параметра
Они могут быть следующих видов:
not
- логическоеНЕ
gte
- больше либо равно (>=)lte
- меньше либо равно (<=)
Иногда необходимо объединить несколько параметров в одну логически связанную группу условий. Например, brand
и model
есть смысл объединять логическим И
, если они связаны. Ниже я опишу это в примерах конвертации. Пока что необходимо знать,
что сгруппировать параметры можно передав в параметре group
их названия разделенные запятой, например: group=brand,model
- Запрос на получение всех записей с
brand.id=9
:
{
"query": {
"bool": {
"must": [
{"term": {"brand.id": {"value": "9"}}}
]
}
}
}
- Запрос на получение всех записей в диапазоне
price.gte=5000&price.lte=10000
:
{
"query": {
"bool": {
"must": [
{"range": {"price": {"gte": "5000", "lte": "10000"}}}
]
}
}
}
- Запрос на получение всех записей, у которых
brand.id.not=9
:
{
"query": {
"bool": {
"must_not": [
{"term": {"brand.id": {"value": "9"}}}
]
}
}
}
- Запрос с несколькими группами параметров
brand.id[0]=9&model.id[0]=98&brand.id[1]=10&model.id[1]=113&group=brand.id,model.id
:
{
"query": {
"bool": {
"must": [
{
"bool": {
"must": [
{"term": {"brand.id": {"value":9}}},
{"term": {"model.id": {"value":98}}}
]
}
},
{
"bool": {
"must": [
{"term": {"brand.id": {"value":10}}},
{"term": {"model.id": {"value":113}}}
]
}
}
]
}
}
}
- Запрос с группами параметров и исключением
brand.id[0].not=9&model.id[0].not=98&brand.id[1]=10&model.id[1]=113&group=brand.id,model.id
:
{
"query": {
"bool": {
"must_not": [
{
"bool": {
"must": [
{"term": {"brand.id": {"value":9}}},
{"term": {"model.id": {"value":98}}}
]
}
}
],
"must": [
{
"bool": {
"must": [
{"term": {"brand.id": {"value":10}}},
{"term": {"model.id": {"value":113}}}
]
}
}
]
}
}
}