想要更好地控制您的搜索设置?了解我们的灵活的基础设施定价

回到主页Meilisearch 的标志
返回文章

如何在您的 React 应用中实现即时搜索

了解如何借助 Meilisearch 和 React 的强大功能,轻松创建基于搜索的 Web 应用,并获得即时可靠的结果。

2022年11月15日6分钟阅读
How to implement instant search in your React app
分享文章

这篇博文最初由客座作者Riccardo Giorato于2020年5月发布,当时Meilisearch的版本是v0.09。它已经由Carolina Ferreira更新,以适用于Meilisearch v1。你可以在GitHub上找到该博文的第一个版本。

简介

在本教程中,您将学习如何利用Meilisearch的强大功能,轻松创建一个基于搜索的Web应用程序,实现即时可靠的搜索结果。

我们将介绍将数据添加到Meilisearch、创建自定义前端搜索的基本步骤,最后再进行定制化。

在本教程中,我们将为一家运动品牌创建一个即时搜索体验。以下是您将要构建的预览:

Searching for multiple items on the decathlon demo using Meilisearch

先决条件

开始之前,请确保您的机器上已安装Node.js >= 18。

您可以按照本教程并边学边写代码,使用此GitHub项目

最后,本教程假设您已经熟悉React。如果不是,您可以查阅React文档以了解更多信息。

入门

克隆仓库

使用以下命令克隆 GitHub 仓库

git clone https://github.com/meilisearch/tutorials.git
cd src/react-decathlon

运行新的 Docker 镜像

如果您克隆了仓库来设置 Meilisearch 实例,只需在主文件夹中执行以下命令

npm install
npm run setup_meili

如果您没有克隆仓库,但想使用 Docker 启动 Meilisearch,请执行此命令

docker run -it --rm 
    -p 7700:7700 
    -e MEILI_ENV='development' 
    -v $(pwd)/meili_data:/meili_data 
    getmeili/meilisearch:v1.0

默认情况下,Meilisearch 的 API 是未受保护的。在生产环境中,您需要一个主密钥。您可以在我们的文档中了解更多信息。

您可以通过访问:https://:7700/ 来检查 Meilisearch 是否正在运行

想避免本地安装?为了快速创建一流的搜索体验,我们提供便捷的Meilisearch Cloud,这是 Meilisearch 的托管和完全管理版本。提供14天免费试用,无需信用卡 😉

在 Meilisearch 中创建索引

索引是存储文档的实体,就像一个附带特定设置的对象数组,并且有一个唯一的主键

每个被索引的文档都必须有一个主字段,这是一个必须存在于所有文档中的特殊字段。该字段保存了文档的唯一值:其id。

Meilisearch 可以从您的数据集中推断出主键,前提是它包含 id 子字符串。您也可以显式设置它。

以下是添加到 Meilisearch 的示例文档。

{
  "id": 100013768717,
  "name": "Fitness Foldable Shoe Bag",
  "url": "https://www.decathlon.com/products/gym-foldable-shoe-bag",
  "vendor": "Domyos",
  "category": "Sport bag",
  "tags": [
    "Artistic Gymnastics",
    "Boy's",
    "CARDIO_FITNESS_ACCESSORIES",
    "CARDIO_FITNESS_BAGS",
    "CODE_R3: 11782"
  ],
  "images": "https://cdn.shopify.com/s/files/1/1330/6287/products/sac_20a_20chaussure_20kaki_20_7C_20001_20_7C_20PSHOT_20_490180e6-44e4-4340-8e3d-c29eb70c6ac8.jpg?v=1584683232",
  "creation_date": "2020-04-03T15:58:48-07:00",
  "price": "2.49"
}

您可以使用 REST 客户端(如 Postman)轻松创建此索引,但在本教程中,我们将使用 Meilisearch Javascript SDK 直接从 Node.js 执行此操作。

const { MeiliSearch } = require('meilisearch')

;(async () => {
  try {
    const config = {
      host: 'https://:7700'
    };

    const meili = new MeiliSearch(config);
    
    await meili.createIndex('decathlon'); 
    
    // or you can set the primary key explicitly: 
    // await meili.createIndex({ uid: "decathlon", primaryKey: "id" });
        
  } catch (e) {
    console.error(e);
    console.log("Meili error: ", e.message);
  }
})();

您可以在Meilisearch 文档中阅读更多关于索引属性的信息。

索引文档

Meilisearch 接收 JSON 格式的文档并将其存储以供搜索。这些文档由可以保存任何类型数据的字段组成。Meilisearch 还接受以下格式的数据集:NDJSON 和 CSV。您可以在文档中阅读更多关于格式的信息。

在本教程中,您可以下载包含运动服饰商品的此数据集:decathlon.json

使用以下脚本将此 JSON 文件中的所有对象上传到 Meilisearch。请记住,在运行之前更改您的 JSON 文件路径!

const { MeiliSearch } = require('meilisearch')

;(async () => {
  try {
    const config = {
      host: 'https://:7700'
    };

    const meili = new MeiliSearch(config);

    const decathlon = require("../decathlon.json"); // path to json file

    const index = meili.index("decathlon");
    
    await index.addDocuments(decathlon);
        
  } catch (e) {
    console.error(e);
    console.log("Meili error: ", e.message);
  }
})();

准备 React 应用

我们需要一个标准的 React 应用。您可以使用之前在“入门”部分克隆的项目。

如果您喜欢从一个空应用程序开始,可以使用下面的命令通过 Create React App 创建自己的应用程序。您可以随意命名应用程序。

npx create-react-app meili_react_demo
cd meili_react_demo

包含 Tailwind CSS

为了加快样式设置过程,请将 Tailwind CSS 样式直接添加到 index.html 文件的 <head> 元素中

  <script src="https://cdn.tailwindcss.com"></script>

配置 App.js 状态

然后,使用此代码修改 App.js 文件,以设置一个简单的搜索表单和几个状态变量来处理搜索的各个方面。

import React, { useState, useEffect } from 'react'
import { MeiliSearch } from 'meilisearch'
import Item from './components/Item'

// TODO configure the MeiliSearch Client

const index = client.index('decathlon')

function App () {
  const [searchedWord, setSearch] = useState('')
  const [resultSearch, setResults] = useState([])

  // TODO add function to send searchedWord to Meilisearch

  return (
    <div className='mx-auto'>
      <div className='header font-sans text-white items-center justify-center'>
        <header className='py-12'>
          <img
            className='h-20 w-auto items-center justify-center p-2 mx-auto'
            src='/wide_logo.png'
            style={{ filter: 'invert(0%)' }}
            alt='Decathlon logo'
          />
          <h1 className='flex flex-wrap flex-grow text-3xl w-full justify-center p-4'>
            Stop looking for an item — find it and work hard!
          </h1>
          <div className='border rounded overflow-hidden w-full flex justify-center mx-auto searchBox mt-6'>
            <button className='flex items-center justify-center px-4 shadow-md bg-white text-black'>
              <svg
                className='h-4 w-4 text-grey-dark'
                fill='currentColor'
                xmlns='http://www.w3.org/2000/svg'
                viewBox='0 0 24 24'
              >
                <path d='M16.32 14.9l5.39 5.4a1 1 0 0 1-1.42 1.4l-5.38-5.38a8 8 0 1 1 1.41-1.41zM10 16a6 6 0 1 0 0-12 6 6 0 0 0 0 12z' />
              </svg>
            </button>
            <input
              type='text'
              value={searchedWord}
              onChange={(event) => setSearch(event.target.value)}
              className='px-6 py-4 w-full text-black'
              placeholder='Product, sport, color, …'
            />
          </div>
        </header>
      </div>
      <div>
        <div className='flex flex-wrap searchResults'>
          // TODO iterate over the search results to display them with the Item component
        </div>
      </div>
    </div>
  )
}

export default App


此代码应输出此漂亮的带有搜索表单的标题。

Decathlon header with a search bar

React 中的搜索结果

使用 Javascript SDK 将 React 与 Meilisearch 连接是一个简单的操作,只需几个步骤即可完成。

Meilisearch 客户端

使用以下命令安装 Meilisearch SDK

// if you use npm
npm install meilisearch
// if you use yarn
yarn add meilisearch

使用服务器 URL 设置 Meilisearch 客户端。在我们的例子中,它是 localhost Docker 机器。最后,从后端加载正确的索引。

用以下代码片段替换 App.js 中的此注释

"// TODO configure the Meilisearch Client"

import { MeiliSearch } from "meilisearch";

const client = new MeiliSearch({
  host: "https://:7700/",
});

const index = client.index("decathlon");

发送搜索查询

添加一个 useEffect 钩子,用于执行已输入单词在 Meilisearch 中的搜索。所有结果都将设置为一个名为 resultsSearch 的简单状态变量。

用以下代码片段替换 App.js 中的此注释

"// TODO add function to send searchedWord to Meilisearch"

  useEffect(() => {
    // Create a scoped async function in the hook
    async function searchWithMeili() {
      const search = await index.search(searchedWord);
      setResults(search.hits);
    }
    // Execute the created function directly
    searchWithMeili();
  }, [searchedWord]);

展示成果

您将遍历 Meilisearch 返回的 JSON 对象——它们的结构与上传的 JSON 对象相同——并将它们显示在 Item 组件中,链接到产品页面。

让我们创建 Item 组件,它将帮助我们显示产品。创建一个名为 components 的文件夹,并在其中创建一个 Item.js 文件,然后复制粘贴以下代码片段

function Item ({ url, image, name, category, vendor, price, id }) {
  return (
    <div className='flex w-full sm:w-1/2 md:w-1/3 lg:w-1/4 xl:w-1/6 p-3' key={id}>
      <a className='flex-1 rounded overflow-hidden shadow-lg' href={url}>
        <img
          className='w-full h-48 object-cover'
          src={image}
          alt={name}
          onError={(e) => {
            e.target.onerror = null
            e.target.src = '/wide_logo.png'
          }}
        />
        <div className='px-6 py-3'>
          <div className='font-bold text-sm mb-1 text-gray-600 capitalize'>
            {category}
          </div>
          {name}
          <div className='font-bold text-xl mb-2 text-gray-800'>
            {vendor} -
          </div>
          <p className='text-black text-xl font-bold text-base py-2'>
            $ {price}
          </p>
        </div>
      </a>
    </div>
  )
}

export default Item

然后,用以下代码片段替换 App.js 中的此注释

{resultSearch?.map((result) => (
    <Item
      url={result.url}
      image={result.images}
      name={result.name}
      category={result.category}
      vendor={result.vendor}
      price={result.price}
      key={result.id}
      />
))}

您可以在 GitHub 上查看完整代码。

使用 Meilisearch,您可以获得大量的自定义选项,用于微调您的搜索体验。我们将在这里介绍一些功能。您可以在文档中了解更多信息。

搜索排名

我们将从更改排序规则开始,即 Meilisearch 在进行搜索查询时用于对您上传的文档进行排序的标准。排序规则的顺序会影响搜索结果的相关性。您可以在文档中了解更多信息。

让我们使用以下顺序

[
  "words",
  "typo",
  "proximity",
  "attribute",
  "sort",
  "exactness",
  “creation_date:desc”
]

这使用了默认顺序以及一个自定义规则:creation_date。如果所有先前的值都相同,此规则将按创建日期对项目进行排名。

可搜索属性

您还可以配置可搜索属性。这些属性的值是 Meilisearch 搜索匹配查询词的。默认情况下,所有属性都是可搜索的,但您可以将其配置为仅搜索 namevendorcategorytags 字段,而不包括 imagesURL

searchableAttributes: ["name", "vendor", "category", "tags"]

显示属性

显示属性是 Meilisearch 可以通过 displayedAttributes 数组返回给前端用户的属性。与可搜索属性一样,默认情况下所有属性都显示。

    "displayedAttributes": [
      "name",
      "vendor",
      "category",
      "tags",
      "images",
      "url"
    ]

将新设置上传到 Meilisearch

是时候使用上面解释的搜索设置自定义我们的 Meilisearch 索引了。

const { MeiliSearch } = require('meilisearch')

;(async () => {
  try {
    const config = {
      host: 'https://:7700'
    };

    const meili = new MeiliSearch(config);
    
    const index = meili.index("decathlon");

    const newSettings = {
      rankingRules: [
        "words",
        "typo",
        "proximity",
        "attribute",
        "sort",
        "exactness",
        "creation_date:desc"
      ],
      searchableAttributes: ["name", "vendor", "category", "tags"],
      displayedAttributes: [
        "name",
        "vendor",
        "category",
        "tags",
        "images",
        "url"
      ]
    };

    await index.updateSettings(newSettings);
        
  } catch (e) {
    console.error(e);
    console.log("Meili error: ", e.message);
  }
})();


结论

如果没有一个了不起的团队夜以继日地投入到这个伟大的项目中,这种快速搜索是不可能实现的!如果您喜欢为 Meilisearch 大家庭做贡献,请查看以下仓库


订阅我们的时事通讯,每月获取这些更新,直接发送到您的收件箱。

更多关于 Meilisearch 的内容,请加入我们的开发者社区,地址在 Discord。您可以通过查看路线图和参与产品讨论来了解更多关于产品的信息。

Meilisearch indexes embeddings 7x faster with binary quantization

Meilisearch 使用二值量化将嵌入索引速度提高7倍

通过在向量存储 Arroy 中实现二值量化,显著减少了大型嵌入的磁盘空间使用和索引时间,同时保持了搜索相关性和效率。

Tamo
Tamo2024年11月29日
How to add AI-powered search to a React app

如何向 React 应用添加 AI 驱动的搜索

使用 Meilisearch 的 AI 驱动搜索构建 React 电影搜索和推荐应用。

Carolina Ferreira
卡罗莱纳·费雷拉2024年9月24日
Meilisearch is too slow

Meilisearch 太慢了

在这篇博文中,我们探讨了 Meilisearch 文档索引器所需的增强功能。我们将讨论当前的索引引擎、其缺点以及优化性能的新技术。

Clément Renault
克莱门特·雷诺2024年8月20日
© . This site is unofficial and not affiliated with Meilisearch.