AI 驅動的混合搜尋目前為封閉測試階段。 加入候補名單以搶先體驗!

前往首頁Meilisearch 的標誌
返回文章
2022 年 11 月 15 日

如何在你的 React 應用程式中實作即時搜尋

了解如何藉由 Meilisearch 和 React 的強大功能,輕鬆建立具有即時且可靠結果的搜尋型網路應用程式。

Riccardo Giorato
Riccardo GioratoMeilisearch 團隊@RiccardoGiorato
How to implement instant search in your React app

這篇文章最初由客座作者 Riccardo Giorato 於 2020 年 5 月發表,當時 Meilisearch 的版本為 v0.09。文章已由 Carolina Ferreira 更新,以適用於 Meilisearch v1。您可以在 GitHub 上找到此文章的第一個版本。

簡介

在本教學中,您將學習如何藉由 Meilisearch 的強大功能,輕鬆建立具有即時且可靠結果的搜尋型網路應用程式。

我們將涵蓋將資料新增至 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 是否正在執行:https://127.0.0.1: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: 'https://127.0.0.1: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://127.0.0.1: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 用戶端。在我們的案例中,它是本機 Docker 機器。最後,從後端載入正確的索引。

App.js 中的此註解取代為以下程式碼片段

"// TODO 設定 Meilisearch 用戶端"

import { MeiliSearch } from "meilisearch";

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

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

傳送搜尋查詢

新增一個 useEffect hook,以執行在 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 元件,以協助我們顯示產品。建立一個 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://127.0.0.1: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 上的開發者社群。您可以查看路線圖,並參與產品討論,以了解更多關於該產品的資訊。

How to add AI-powered search to a React app

如何將 AI 驅動的搜尋功能添加到 React 應用程式

使用 Meilisearch 的 AI 驅動搜尋功能建立 React 電影搜尋和推薦應用程式。

Carolina Ferreira
Carolina Ferreira2024 年 9 月 24 日
Build your Next.js Shopify storefront with Blazity

使用 Blazity 建立您的 Next.js Shopify 商店

學習如何使用 Next.js 和 Blazity commerce starter 建立 Shopify 商店。

Laurent Cazanove
Laurent Cazanove2024 年 8 月 19 日
Meilisearch 1.8

Meilisearch 1.8

Meilisearch 1.8 帶來了負關鍵字搜尋、搜尋穩健性的改進和 AI 搜尋,包括新的嵌入器。

Carolina Ferreira
Carolina Ferreira2024 年 5 月 7 日