Мы создадим пользовательский интерфейс для поиска книг в электронной коммерции с помощью React и Elasticsearch - менее чем за 60 минут!
Для создания пользовательского интерфейса поиска требуются два ключевых компонента:
- Мощный поисковый бэкэнд - здесь Elasticsearch отвечает всем требованиям, будучи поисковой системой №1.
- Хорошо спроектированный пользовательский интерфейс - React - отличный выбор для этого.
Однако эффективное владение этими двумя мощными инструментами требует много работы. Например, необходимо правильно настроить отображение, анализаторы и токенизаторы, иначе вы не сможете получить обратно точные результаты поиска. Кроме того, чем больше фильтров применяется вместе с поисковым запросом, тем сложнее становится результирующий поисковый запрос. А создание представлений пользовательского интерфейса, управляемых данными, в которых состояние синхронизируется с серверной частью, - нетривиальная задача.
Здесь на помощь приходит ReactiveSearch, библиотека компонентов пользовательского интерфейса React с открытым исходным кодом для Elasticsearch, участником которой я являюсь. Он предлагает более 25 разнообразных компонентов пользовательского интерфейса, которые обеспечивают мощную основу для создания пользовательских интерфейсов поиска на основе данных.
В этом посте я покажу, как использовать ReactiveSearch для создания пользовательского интерфейса книжного поиска менее чем за час.
Прежде чем мы начнем
Нам понадобится хороший набор данных. Мы позаимствуем одну о Goodbooks с https://github.com/zygmuntz/goodbooks-10k. Вы можете проверить очищенную версию, которая уже проиндексирована в Elasticsearch, здесь.
Затем нам понадобится индекс Elasticsearch для размещения наших серверных данных. В этом посте мы будем использовать для этого appbase.io, но вы также можете запустить свой собственный кластер Elasticsearch и создать индекс.
Если вы выберете клонирование указанного выше набора данных, вы уже создали бы приложение appbase.io.
Начало работы с приложением Create React
Теперь, когда у нас есть набор данных и определение индексации, мы готовы приступить к созданию приложения.
Мы инициализируем шаблон с настройкой CRA.
npm install -g create-react-app # install CRA if you don't have it. create-react-app booksearch # initialize the boilerplate. cd booksearch
Давайте протестируем приложение CRA по умолчанию, запустив npm start
.
Одним из больших преимуществ использования CRA является то, что он работает без необходимости настраивать конфигурацию сборки.
Добавить ReactiveSearch
Затем установите @appbaseio/reactivesearch
через npm.
npm install --save @appbaseio/[email protected]
Примечание. ReactiveSearch v3 теперь доступен, и этот пост несовместим с ним. Установка v2.16.1 (или любой другой версии v2.x) гарантирует, что вы сможете следить за этим постом как есть.
Все компоненты ReactiveSearch обернуты внутри компонента-контейнера - ReactiveBase
, который склеивает индекс Elasticsearch и компоненты ReactiveSearch вместе. Отредактируйте src/App.js
файл.
import React, { Component } from 'react'; import { ReactiveBase } from '@appbaseio/reactivesearch'; class App extends Component { render() { return ( <ReactiveBase app="good-books-ds" credentials="nY6NNTZZ6:27b76b9f-18ea-456c-bc5e-3a5263ebc63d" > Hello from Reactive Search! </ReactiveBase> ); } } export default App;
app
и credentials
относятся к имени индекса и любым учетным данным, которые вы могли настроить для авторизации доступа. ReactiveBase также поддерживает свойство url
, которое принимает URL-адрес кластера Elasticsearch.
Note:
Вы должны либо использовать учетные данные только для чтения, либо иметь промежуточное программное обеспечение авторизации, к которому ReactiveBase подключается для обеспечения безопасного доступа в производственной сборке.
Давайте запустим сервер с npm start
.
Добавление компонентов пользовательского интерфейса
Компоненты, которые нам понадобятся для начала:
- Окно поиска данных о книгах,
- Фильтр рейтингов книг,
- Результат показа книг.
DataSearch
<DataSearch componentId="mainSearch" dataField={["original_title", "authors"]} queryFormat="and" />
componentId
- обязательное свойство, которое требует указания уникальной строки, которая используется внутри ReactiveSearch lib, а также некоторыми другими пользовательскими реквизитами.
dataField
prop сообщает DataSearch, какие поля следует запрашивать. Он может принимать либо строку (одно поле), либо массив строк (несколько полей).
Значение и queryFormat
prop указывает DataSearch возвращать только те результаты, в которых поисковый запрос присутствует во всех значениях dataField.
Со временем мы выполним дополнительные настройки на следующих этапах. Вы можете найти полный справочник компонента DataSearch здесь.
SingleRange
<SingleRange componentId="ratingsFilter" dataField="average_rating_rounded" title="Book Ratings" data={[ { start: 4, end: 5, label: "★★★★ & up" }, { start: 3, end: 5, label: "★★★ & up" }, { start: 2, end: 5, label: "★★ & up" }, { start: 1, end: 5, label: "★ & up" } ]} />
data
prop здесь позволяет нам определять параметры диапазона [начало, конец] с помощью значения метки. Когда пользователь выбирает один из вариантов диапазона, к dataField применяется запрос диапазона с выбранными конечными точками диапазона.
Вы можете найти полное описание компонента SingleRange здесь.
ResultCard
<ResultCard componentId="results" dataField="original_title" react={{ and: ["mainSearch", "ratingsFilter"] }} onData={(res) => ( { "image": res.image, "title": res.title, "description": res.average_rating + " ★ " } )} />
Как следует из названия, компонент ResultCard отображает результаты в виде карты.
react
prop сообщает компоненту ResultCard создать запрос на основе отдельных запросов, используемых в компонентах DataSearch и SingleRange, которые мы определили выше (на которые ссылается их значение componentId
).
onData
prop - это функция, которая принимает один объект попадания в качестве аргумента и возвращает разметку карты.
Полную справку о том, что позволяет компонент ResultCard, можно найти здесь.
Объединение элементов
Давайте объединим эти три компонента в файл src/App.js
.
import React, { Component } from 'react'; import { ReactiveBase, DataSearch, SingleRange, ResultCard } from '@appbaseio/reactivesearch'; class App extends Component { render() { return ( <ReactiveBase app="good-books-ds" credentials="nY6NNTZZ6:27b76b9f-18ea-456c-bc5e-3a5263ebc63d" > <DataSearch componentId="mainSearch" dataField={["original_title", "original_title.search", "authors", "authors.search"]} queryFormat="and" iconPosition="left" /> <SingleRange componentId="ratingsFilter" dataField="average_rating_rounded" title="Book Ratings" data={[ { start: 4, end: 5, label: "★★★★ & up" }, { start: 3, end: 5, label: "★★★ & up" }, { start: 2, end: 5, label: "★★ & up" }, { start: 1, end: 5, label: "★ & up" }, ]} react={{ and: "mainSearch" }} /> <ResultCard componentId="results" dataField="original_title" react={{ "and": ["mainSearch", "ratingsFilter"] }} onData={(res)=>({ "image": res.image, "title": res.original_title, "description": res.average_rating + " ★ " })} /> </ReactiveBase> ); } } export default App;
Давайте запустим сервер и посмотрим, как выглядит пользовательский интерфейс с npm start
.
Вы должны увидеть полностью работающий пользовательский интерфейс, который работает. Введите поисковый запрос, чтобы увидеть результаты, отраженные в пользовательском интерфейсе карточек. Единственное, чего не хватает на данный момент, - это компоновка макета и стили. Мы добавим их на следующем шаге.
Примечание. Мы пока не особо беспокоились и смогли обойти сложность DSL запросов Elasticsearch, нам не нужно было писать сложную логику рендеринга или управлять привязками состояний к нашему представлению пользовательского интерфейса.
Добавление стилей и макета
ReactiveSearch предоставляет нам компоненты с ограниченными стилями, оставляя выбор макета на усмотрение пользователя. В этом посте мы будем использовать Flex для упорядочивания компонентов, но мы также могли бы использовать Materialize, Bootstrap или CSS Grid. Если вы новичок в Flex, рекомендую прочитать эту статью.
Мы добавим панель навигации и дадим нашему приложению красивый логотип, а также добавим макет и стили для каждого из компонентов. Для этого мы воспользуемся реквизитами className
и innerClass
.
Вот наш последний src/App.js
с изменениями.
На этот раз мы также импортируем src/App.css
, чтобы включить наши пользовательские стили.
Большая часть таблицы стилей здесь посвящена настройке макета.
После изменения этих двух файлов и запуска npm start
вы должны увидеть такой интерфейс.
Выглядит намного лучше, правда!
Если вам не хватает шага, вы можете получить код, выполнив следующие действия:
git clone [email protected]:appbaseio-apps/booksearch.git cd booksearch && git checkout basic-app npm install && npm start # go to http://localhost:3000
Что делать дальше?
Мы лишь поверхностно коснулись того, что можно построить. Вот некоторые идеи, которые вы можете использовать здесь:
- Добавьте больше фильтров (ReactiveSearch предлагает более 20 компонентов),
- Добавьте параметры сортировки, чтобы разрешить различный порядок результатов,
- Добавьте поток входа в систему OAuth и разрешите только пользователям, выполнившим вход, видеть это представление пользовательского интерфейса.
Я создал аромат с некоторыми дополнительными фильтрами, который выглядит так:
Я добавил сюда два новых компонента: RangeSlider и MultiList, а также изменил некоторые свойства компонентов DataSearch и ResultCard.
Вы также можете увидеть его код на странице https://github.com/appbaseio-apps/booksearch/tree/master.
Заключение
Мы перешли от шаблона с CRA к созданию пользовательского интерфейса книжного поиска, основанного на данных, и, надеюсь, в течение 60 минут.
Вот несколько релевантных ссылок, которые помогут в дальнейшем изучении:
- Репозиторий кода - https://github.com/appbaseio-apps/booksearch,
- ReactiveSearch Repo - https://github.com/appbaseio/reactivesearch,
- Компоненты детской площадки - https://opensource.appbase.io/playground/,
- Документация - https://opensource.appbase.io/reactive-manual/.