AI 驅動的混合搜尋功能正在封閉測試中。 加入候補名單 以搶先體驗!

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

如何使用 Meilisearch 和 React 將極速且相關的搜尋功能整合到您的 Rails 應用程式中

將 Meilisearch 與您的 Rails 應用程式資料庫整合,並使用 React 建立即時搜尋體驗。

Carolina Ferreira
Carolina FerreiraMeilisearch 開發者宣傳@CarolainFG
How to integrate an extremely fast and relevant search into your Rails app using Meilisearch and React

本教學課程最初於 2021 年 11 月發布,當時最新的 Meilisearch 版本為 0.24。現在已更新為與 Meilisearch v1.0 相容

簡介

在本教學課程中,您將學習如何將 Meilisearch 與您的 Rails 應用程式資料庫整合,並使用 React 快速建立具有即時搜尋體驗的前端搜尋列。

我們將建立一個非常基本的應用程式;我們的主要重點將放在搜尋上。因此,我們不會詳細說明 Rails 或 React。

先決條件

若要依照本教學課程進行,您需要

理想情況下,您應該熟悉 Ruby on Rails 並且已經建立了一個簡單的 RoR 應用程式。如果不是這種情況,您仍然可以按照本教學課程進行,但正如我們在簡介中所述,說明將重點放在搜尋上。

步驟 1. 安裝 Meilisearch

安裝 Meilisearch 的方法有很多種。執行 Meilisearch 執行個體的簡單方法是使用Meilisearch Cloud,有 14 天免費試用期,無需信用卡。Meilisearch 是開放原始碼的。在本教學課程中,我們將使用 cURL 在本機執行它,這是一個可讓您從命令列發出 HTTP 要求和傳輸資料的工具。

開啟您的終端機並貼上以下程式碼

# Install Meilisearch
curl -L https://install.meilisearch.com | sh

# Launch Meilisearch
./meilisearch

步驟 2. 建立和設定您的 Rails 應用程式

現在您已經啟動並執行 Meilisearch,讓我們建立我們的 RoR 應用程式。‌‌ 我們將建立一個名為 delicious_meals 的簡單食譜應用程式。在終端機上執行以下命令

rails new delicious_meals -j esbuild

‌讓我們產生我們的模型 Recipe。它將有四個屬性

  1. 標題
  2. 食材
  3. 做法
  4. 飲食

進入專案資料夾並執行以下命令

bin/rails g model Recipe title:string ingredients:text directions:text diet:string

此命令也會在 db/migrate 目錄中產生移轉檔案。讓我們在資料表的每個資料行旁邊新增 null: false 選項,這樣如果欄位為空,就不會將任何食譜儲存到資料庫中。

class CreateRecipes < ActiveRecord::Migration[7.0]
  def change
    create_table :recipes do |t|
      t.string :title, null: false
      t.text :ingredients, null: false
      t.text :directions, null: false
      t.string :diet, null: false

      t.timestamps
    end
  end
end

timestamps 資料行方法會在資料表中新增兩個額外欄位:created_atupdated_at

現在您可以使用以下命令建立資料庫並執行上述移轉

# Creates the database 
bin/rails db:create 

# Runs the migration 
bin/rails db:migrate

接下來,您需要產生具有其 index 動作的控制器。

bin/rails g controller Recipes index

我們將使用 index 檢視來顯示我們的食譜,並使用搜尋列搜尋它們。我們不會產生其餘的 CRUD 動作,因為這會超出本教學課程的目的。

建立控制器後,請修改 config/routes.rb 檔案,使其如下所示

Rails.application.routes.draw do
  # Maps requests to the root of the application to the index action of the 'Recipes controller'
  root "recipes#index"
end

現在,root 路由對應到 RecipesControllerindex 動作。這樣一來,app/views/recipes/index.html.erb 的內容將會在應用程式的根目錄中轉譯。

您可以使用以下命令啟動應用程式來檢查一切是否如預期般運作

bin/dev

開啟您的瀏覽器視窗並瀏覽至 http://127.0.0.1:3000。您應該會看到您的索引檢視顯示如下訊息

Recipes#index

在 app/views/recipes/index.html.erb 中找到我

步驟 3. 將 Meilisearch 新增至您的應用程式

現在我們有了應用程式的後端基礎知識,讓我們使用 meilisearch-rails gem 將其連接到正在執行的 Meilisearch 執行個體。

執行以下命令來安裝它

bundle add meilisearch-rails

當本教學課程上次更新時,gem 的最新版本為 0.8.1。您可以在meilisearch-rails GitHub 儲存庫Meilisearch 發現的 rubygems中查看最新版本。

config/initializers/ 資料夾內建立一個名為 meilisearch.rb 的檔案,以設定您的 MEILISEARCH_HOSTMEILISEARCH_API_KEY

touch config/initializers/meilisearch.rb

如果您已逐字遵循步驟 1,您的 Meilisearch 主機應該是 https://127.0.0.1:7700。由於我們沒有設定任何 API 金鑰,我們將註解掉具有 meilisearch_api_key 欄位的程式碼行

MeiliSearch::Rails.configuration = {
    meilisearch_url: 'https://127.0.0.1:7700',
    # meilisearch_api_key: ''
}

您在生產環境中會需要主金鑰或私密金鑰,您可以在這裡深入了解。

如果您已設定主金鑰,則必須先更新您的組態,才能執行 Meilisearch(請參閱步驟 1)讓我們開啟我們的 app/models/recipe.rb 檔案,並在 Class 宣告中新增以下程式碼行

include MeiliSearch::Rails

我們還需要新增一個 meilisearch block。請注意,Meilisearch block 內的設定並非強制性的。

class Recipe < ApplicationRecord
    include MeiliSearch::Rails
    
    meilisearch do
        # all attributes will be sent to Meilisearch if block is left empty
        displayed_attributes [:id, :title, :ingredients, :directions, :diet]
        searchable_attributes [:title, :ingredients, :directions, :diet]
        filterable_attributes [:diet]
    end
end

讓我們分解每一行程式碼

設定顯示的屬性

displayed_attributes [:id, :title, :ingredients, :directions, :diet]

根據預設,Meilisearch 會顯示所有屬性。在這裡,我們指示 Meilisearch 只在搜尋回應中顯示指定的屬性,此設定會防止 Meilisearch 顯示 created_atupdated_at 欄位。

您可以在我們的說明文件中深入了解 displayed attributes

設定可搜尋的屬性

searchable_attributes [:title, :ingredients, :directions, :diet]

透過上面的程式碼行,我們正在做兩件事

  1. 我們首先告訴 Meilisearch 在執行搜尋查詢時僅在指定的屬性中搜尋。因此它不會嘗試在 idcreated_atupdated_at 欄位中尋找相符項目。
  2. 我們還指定屬性的重要性順序。我們告訴 Meilisearch,標題中找到相符查詢字的文件的相關性高於做法中找到相符查詢字的文件。第一個文件更相關,並在搜尋結果中首先傳回。

請在我們的說明文件中深入了解 searchable fields

設定可篩選的屬性

filterable_attributes [:diet] 

最後,我們告訴 Meilisearch,我們希望能夠根據飲食類型精簡我們的搜尋結果。這將允許我們例如只搜尋素食食譜。

請瀏覽我們的說明文件,以深入了解篩選。

步驟 4. 為資料庫設定種子

若要測試我們的應用程式,我們需要在資料庫中加入一些資料。最快的方法是使用名為 faker 的 gem,以虛擬資料來填入資料庫。

將以下程式碼行新增至您開發群組內的 Gemfile,儲存並執行 bundle install

gem 'faker', :git => 'https://github.com/faker-ruby/faker.git', :branch => 'master' 

然後開啟 ./db/seeds.rb 檔案並新增以下程式碼,以 1000 個食譜填入您的資料庫

# Deletes existing recipes, useful if you seed several times
Recipe.destroy_all

# Creates 1000 fake recipes
1000.times do
    Recipe.create!(
        title: "#{Faker::Food.dish} by #{Faker::Name.unique.name}",
        ingredients: "#{Faker::Food.ingredient}, #{Faker::Food.ingredient}, #{Faker::Food.ingredient}",
        directions: Faker::Food.description,
        diet: ['omnivore', 'pescetarian', 'vegetarian', 'vegan'].sample
    )
end 

# Displays the following message in the console once the seeding is done
puts 'Recipes created'

現在,在命令列中執行 bin/rails db:seed

步驟 5. 使用搜尋預覽測試搜尋

Meilisearch 提供現成的 Web 介面,可互動式地進行測試。開啟您的瀏覽器並前往 Meilisearch HTTP 位址,除非您在啟動時另行指定,否則該位址應為https://127.0.0.1:7700

將文件新增至索引是一種非同步作業,如果您沒有立即看到 1000 個文件,請別擔心。更新可能需要一些時間才能處理。在這裡深入了解非同步更新。

請確定在位於右上角、搜尋列旁邊的功能表中已選取 Recipe 索引。

如您所見,資料已自動新增至我們的 Meilisearch 實例中。唯一可見和可搜尋的屬性是那些我們在模型檔案的 meilisearch block 內指定的屬性。請注意,由於faker會隨機產生資料,您的搜尋結果可能與 GIF 中顯示的不同。

這對於測試 Meilisearch 及其某些功能很有幫助,但它並未展示我們在區塊中指定的 filterable_attributes。我們需要一個用於生產環境的自訂 UI。

步驟 6. 將 React 加入 Rails 應用程式

將 ReactJS 與 Rails 一起使用有多種方法。我們選擇了最直接的一種:將其作為 JavaScript 依賴項安裝在我們的 Rails 應用程式中。

執行以下命令以安裝 ReactJS 及其用於處理 DOM 的 react-dom 套件

yarn add react react-dom

讓我們為 React 程式碼建立資料夾和檔案。

mkdir app/javascript/recipes 
touch app/javascript/recipes/index.jsx 
touch app/javascript/recipes/App.jsx

讓我們開啟 app/javascript/recipes/index.jsx 並新增必要的程式碼以渲染我們的 React 元素

import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';

const container = document.getElementById('app');
const root = createRoot(container); 
root.render(<App/>);

開啟 app/javascript/application.js 並匯入我們剛剛建立的檔案

import "./recipes"

步驟 7. 整合前端搜尋欄

要整合前端搜尋欄,您需要安裝兩個套件

  • React InstantSearch:一個開放原始碼程式庫,提供您自訂搜尋欄環境所需的所有前端工具
  • Instant Meilisearch:Meilisearch 用戶端,用於建立您的 Meilisearch 實例與 React InstantSearch 程式庫之間的通訊
yarn add react-instantsearch-dom @meilisearch/instant-meilisearch

現在,您可以開啟您的 app/javascript/recipes/App.jsx 檔案,並將現有程式碼替換為 meilisearch-react 入門指南 中的程式碼。我們只需要使用我們的 Meilisearch 主機和 Meilisearch API 金鑰修改 searchClient,以及 indexName。它應該看起來像這樣

import React from "react"
import { InstantSearch, Highlight, SearchBox, Hits } from 'react-instantsearch-dom';
import { instantMeiliSearch } from '@meilisearch/instant-meilisearch';

const searchClient = instantMeiliSearch(
  "https://127.0.0.1:7700", // Your Meilisearch host
  "" // Your Meilisearch API key, if you have set one
);

const App = () => (
  <InstantSearch
    indexName="Recipe" // Change your index name here
    searchClient={searchClient}
  >
    <SearchBox />
    <Hits hitComponent={Hit} />
  </InstantSearch>
);

const Hit = ({ hit }) => <Highlight attribute="title" hit={hit} />

export default App

現在,前往您的 views 資料夾,並將 app/views/recipes/index.html.erb 的內容替換為以下程式碼

<div id="app"></div>

現在您可以執行 bin/dev 命令,開啟您的瀏覽器並導覽至 http://127.0.0.1:3000 並查看結果:‌

嗯,搜尋功能正常運作,但不是很美觀。幸運的是,InstantSearch 提供了一個 CSS 主題,您可以將以下連結插入 app/views/layouts/application.html.erb<head> 元素中來新增。

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/instantsearch.css@7.4.5/themes/satellite-min.css" integrity="sha256-TehzF/2QvNKhGQrrNpoOb2Ck4iGZ1J/DI4pkd2oUsBc=" crossorigin="anonymous">

如果您想,您也可以自訂小工具或建立自己的小工具。有關更多詳細資訊,請查看 React InstantSearch 文件

讓我們檢查一下渲染效果

還不錯,對吧?但是,我們再次缺少依飲食類型篩選結果的可能性。

步驟 8. 加入刻面搜尋

就像在您的 App.jsx 檔案中匯入 RefinementList 小工具一樣簡單

import { InstantSearch, Highlight, SearchBox, Hits, RefinementList } from 'react-instantsearch-dom';

並將其新增到我們的 InstantSearch 小工具中,指定我們想要篩選的屬性

<RefinementList attribute="diet" />

為了使其更美觀和實用,讓我們建立兩個 <div> 元素來分隔我們的元件。在左側,我們會找到篩選器,右側則是搜尋欄和結果。

您也可以新增「飲食類型」標題以及 ClearRefinements 小工具。它允許您只需按一下即可清除所有篩選器,而不必逐一取消選取它們。

現在,該檔案應該看起來像這樣

import React from "react"
import { InstantSearch, Highlight, SearchBox, Hits, RefinementList, ClearRefinements } from 'react-instantsearch-dom';
import { instantMeiliSearch } from '@meilisearch/instant-meilisearch';

const searchClient = instantMeiliSearch(
  "https://127.0.0.1:7700",
  ""
);

const App = () => (
  <InstantSearch
    indexName="Recipe" // Change your index name here
    searchClient={searchClient}
  >
    <div className="left-panel">
      <ClearRefinements />
      <h2>Type of diet</h2>
      <RefinementList attribute="diet" />
    </div>
    <div className="right-panel">
      <SearchBox />
      <Hits hitComponent={Hit} />
    </div>

  </InstantSearch>
);

const Hit = ({ hit }) => <Highlight attribute="title" hit={hit} />

export default App


為了使此功能運作,我們需要新增一些 CSS。讓我們建立一個 app/assets/stylesheets/recipes.css 檔案並新增以下程式碼行

.right-panel {
    margin-left: 210px;
}
  
.left-panel {
    float: left;
    width: 200px;
}

為了使其更加美觀,讓我們在主體和搜尋欄中新增一些邊距和邊框,並變更字體

/* app/assets/stylesheets/recipes.css */

body { 
    font-family: sans-serif; 
    padding: 1em; 
}

.ais-SearchBox { 
    margin: 1em 0; 
}

.right-panel {
    margin-left: 210px;
}

.left-panel {
    float: left;
    width: 200px;
}

鏘鏘!🎉  您現在有一個漂亮的搜尋欄,可以隨打即搜!🥳

⚠️ 因為我們使用假資料來初始化我們的資料庫,所以食譜的 titleingredientsdirectionsdiet 類型不一定一致。

結論

我們已學習如何將我們的 Ruby on Rails 資料庫與 Meilisearch 同步,並直接在我們的 Rails 應用程式上自訂我們的搜尋設定,讓我們能夠以毫秒為單位搜尋我們的資料。最重要的是,我們還使用 React 建立了一個具有隨打即搜體驗的刻面搜尋介面。

多虧 Meilisearch RailsInstant Meilisearch,我們已順利達成所有這一切。Meilisearch 為幾乎所有流行的語言或框架都提供了整合。請查看 Meilisearch 整合指南中的完整清單。

如果您有任何疑問,請在 Discord 上加入我們;我們總是很高興收到您的來信。有關 Meilisearch 的更多資訊,請查看我們的 Github 儲存庫官方文件

How to add AI-powered search to a React app

如何在 React 應用程式中新增人工智慧驅動的搜尋

使用 Meilisearch 的人工智慧驅動搜尋建置一個 React 電影搜尋和推薦應用程式。

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

使用 Blazity 建置您的 Next.js Shopify 店面

學習使用 Next.js 和 Blazity commerce 啟動器建置 Shopify 店面。

Laurent Cazanove
Laurent Cazanove2024 年 8 月 19 日
Meilisearch 1.8

Meilisearch 1.8

Meilisearch 1.8 帶來了否定關鍵字搜尋、搜尋強固性和人工智慧搜尋的改進,包括新的嵌入器。

Carolina Ferreira
Carolina Ferreira2024 年 5 月 7 日