Meilisearch 允许您通过 RESTful API 在极短时间内搜索您的数据。在开发模式下,它提供一个搜索预览,您可以在其中测试您的搜索设置,而无需实现前端。

我知道它很漂亮,但不幸的是,它只对开发人员可见。如果您需要为最终用户提供前端搜索界面,您需要自己动手。但别担心,这并不像听起来那么难。在本教程中,您将学习如何轻松创建自定义前端搜索。为此,我们将使用两个主要工具
- InstantSearch.js:一个开源的前端搜索组件库
- instant-meilisearch:一个用于建立 Meilisearch 实例和 InstantSearch.js 之间通信的插件
它们结合在一起,使您能够轻松地将令人愉快的搜索体验集成到您的前端。
介绍数据集
本教程中使用的数据集直接参考了我们 Strapi 教程 中使用的数据集。我们使用 faker(一个生成假数据的库)添加了更多虚拟餐厅。我们为餐厅添加了一个 picture
字段,其中包含来自 Unsplash 的随机餐厅图片 URL。每家餐厅都有以下字段
name
description
picture
categories
我们添加了两个额外的字段来帮助我们为图片作者提供署名
picture_author
picture_author_profile_link
前端将如下所示

需求
- 运行中的 Meilisearch v1 实例,已索引 餐厅数据集。如果您需要有关此部分的帮助,您可以按照我们的 快速入门指南 进行操作,直到 添加文档 这一步。运行 Meilisearch 实例的最简单方法是使用 Meilisearch Cloud,提供 14 天免费试用,无需信用卡。
- 具有以下已安装软件包的 React 环境
yarn add @meilisearch/instant-meilisearch@^0.11.1 instantsearch.css@^8.0.0 react-instantsearch-dom@^6.39.1
要轻松创建单页 React 应用程序,您可以使用 Create React App。
代码
对于本示例,我们只需要两个文件:App.js
和 index.js
。App.js
将包含您的应用程序代码,而 index.js
将初始化您的 React 应用程序。
您的 index.js
文件应如下所示
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
您无需修改 index.js
,因此让我们看一下 App.js
的代码。
import "instantsearch.css/themes/algolia-min.css";
import React from "react";
import {
InstantSearch,
InfiniteHits,
SearchBox,
Stats,
Highlight
} from "react-instantsearch-dom";
import "./App.css";
import { instantMeiliSearch } from "@meilisearch/instant-meilisearch";
const searchClient = instantMeiliSearch(
"http://localhost:7700",
""
);
const App = () => (
<div className="ais-InstantSearch">
<h1>Restaurants Demo with Meilisearch</h1>
<InstantSearch indexName="restaurant" searchClient={searchClient}>
<Stats />
<SearchBox />
<InfiniteHits hitComponent={Hit} />
</InstantSearch>
</div>
);
const Hit = ({ hit }) => (
<div key={hit.id}>
<div className="hit-name">
<Highlight attribute="name" hit={hit} />
</div>
<p className="hit-categories"><Highlight attribute="categories" hit={hit} /></p>
<div className="hit-image">
<img src={hit.picture} alt={hit.name} width="200px" />
<p className="image-credit">Picture by <a href={hit.picture_author_profile_link}>{hit.picture_author}</a> on <a href="https://unsplash.com/?utm_source=restaurants_demo&utm_medium=referral">Unsplash</a></p>
</div>
<div className="hit-description">
<Highlight attribute="description" hit={hit} />
</div>
</div>
);
export default App;
让我们逐个组件进行分析。
导入所需的组件
以下代码行导入我们需要的搜索组件和客户端,以及样式。
import "instantsearch.css/themes/algolia-min.css";
import React from "react";
import {
InstantSearch,
InfiniteHits,
SearchBox,
Stats,
Highlight
} from "react-instantsearch-dom";
import "./App.css";
import { instantMeiliSearch } from "@meilisearch/instant-meilisearch";
初始化搜索客户端
接下来,我们需要初始化将与 Meilisearch 通信的搜索客户端。将您的 Meilisearch 凭据(主机和 API 密钥)添加为 instantMeilisearch 函数的第一个和第二个参数。如果您已按照我们的 快速入门指南 逐字进行,您的 Meilisearch 主机应该是 http://127.0.0.1:7700。由于我们未设置任何 API 密钥,因此我们可以将第二个参数保留为空字符串。
const searchClient = instantMeiliSearch(
"http://localhost:7700",
"" //your Meilisearch API key, if any
);
添加我们的组件
以下代码添加了我们需要的不同组件
const App = () => (
<div className="ais-InstantSearch">
<h1>Restaurants Demo with Meilisearch</h1>
<InstantSearch indexName="restaurant" searchClient={searchClient}>
<Stats />
<SearchBox />
<InfiniteHits hitComponent={Hit} />
</InstantSearch>
</div>
);
const Hit = ({ hit }) => (
<div key={hit.id}>
<div className="hit-name">
<Highlight attribute="name" hit={hit} />
</div>
<p className="hit-categories"><Highlight attribute="categories" hit={hit} /></p>
<div className="hit-image">
<img src={hit.picture} alt={hit.name} width="200px" />
<p className="image-credit">Picture by <a href={hit.picture_author_profile_link}>{hit.picture_author}</a> on <a href="https://unsplash.com/?utm_source=restaurants_demo&utm_medium=referral">Unsplash</a></p>
</div>
<div className="hit-description">
<Highlight attribute="description" hit={hit} />
</div>
</div>
);
export default App;
让我们一步一步地了解每个组件的作用
<InstantSearch>
:我们的即时搜索的强制包装器。我们需要将searchClient
作为道具提供给此组件,以及 索引名称<Stats>
:显示文档数量和 Meilisearch 查找搜索结果所花费的时间<SearchBox>
:添加搜索栏<InfiniteHits>
:不同Hits
的包装器。它将Hit
(在第 29 行声明)作为道具。Hit
:我们创建的自定义组件,用于确定要展示餐厅的哪些属性
Hit 组件
const Hit = ({ hit }) => (
<div key={hit.id}>
<div className="hit-name">
<Highlight attribute="name" hit={hit} />
</div>
<p className="hit-categories"><Highlight attribute="categories" hit={hit} /></p>
<div className="hit-image">
<img src={hit.picture} alt={hit.name} width="200px" />
<p className="image-credit">Picture by <a href={hit.picture_author_profile_link}>{hit.picture_author}</a> on <a href="https://unsplash.com/?utm_source=restaurants_demo&utm_medium=referral">Unsplash</a></p>
</div>
<div className="hit-description">
<Highlight attribute="description" hit={hit} />
</div>
</div>
);
<img>
将hit.picture
作为道具来显示每家餐厅的图片<Highlight>
组件将属性作为道具,如果该属性中包含查询匹配项,则会突出显示匹配项。第一个是 name,第二个是 categories,第三个是 description。
就是这样;只需几行代码,我们就构建了一个搜索界面。我留给您去个性化它,并用一些 CSS 💅 美化它。
结论
为了更进一步,我们可以使用过滤器来创建一个 多面搜索 界面,并允许用户根据餐厅类别细化搜索结果。但我希望本教程尽可能简单,以帮助您了解将 InstantSearch.js 与 Meilisearch 集成以创建出色的搜索体验是多么容易!
👉 不使用 React?别担心;我们还有其他前端集成。查看 GitHub 上的 列表。
想要了解更多关于 Meilisearch 提供的自定义选项?您可以查看 Meilisearch 101。
如果您有任何问题,请加入我们的 Discord;我们很乐意听到您的声音。如果您想支持我们,您可以为我们的 GitHub 仓库 加星或分享我们的作品 🥰