Meilisearch v1.14 发布啦 ✨ 在我们的博客上阅读更多

返回首页Meilisearch 的标志
返回文章
2022 年 11 月 15 日

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

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

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 是不受保护的。 在生产环境中,您将需要一个主密钥。 您可以在我们的文档中了解更多信息。

您可以通过访问以下链接检查 Meilisearch 是否正在运行:http://localhost:7700/

想要避免本地安装? 为了快速创建一流的搜索体验,我们提供 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: 'http://localhost: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: 'http://localhost: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 配置 Meilisearch 客户端"

import { MeiliSearch } from "meilisearch";

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

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

发送搜索查询

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

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

"// TODO 添加函数以将 searchedWord 发送到 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 组件,它将帮助我们显示我们的产品。 创建一个组件文件夹,并在其中创建一个 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: 'http://localhost: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
Carolina Ferreira2024 年 9 月 24 日
Meilisearch is too slow

Meilisearch 太慢了

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

Clément Renault
Clément Renault2024 年 8 月 20 日