如何快速構(gòu)建優(yōu)異的React搜索體驗
構(gòu)建搜索體驗是一項艱巨的任務(wù)。它初看起來很簡單:構(gòu)建搜索欄,將數(shù)據(jù)放入數(shù)據(jù)庫,然后讓用戶輸入內(nèi)容對數(shù)據(jù)庫進(jìn)行查詢。但是,在數(shù)據(jù)建模、基礎(chǔ)邏輯,當(dāng)然還有總體設(shè)計和用戶體驗方面,還有許多事情需要考慮。
我們接下來介紹如何使用 Elastic 的開源 Search UI庫構(gòu)建出色的基于 React 的搜索體驗。整個過程大約需要 30 分鐘,完成后,您即可將搜索體驗引入任何需要它的應(yīng)用程序當(dāng)中。
但是首先要考慮一下,是什么讓構(gòu)建搜索變得如此具有挑戰(zhàn)性的?
搜索是艱巨的
幾周前,曾熱傳過一篇很棒的名為 Falsehoods Programmers Believe About Search(關(guān)于搜索編程人員相信的謊言)的文章。文章中列出了開發(fā)人員在開發(fā)搜索時所考慮的一系列錯誤假設(shè)。
下列是幾種很多人相信的謊言:
- “知道搜索內(nèi)容的客戶會按照您期望的方式去搜索。”
- “您可以編寫一個始終能夠成功解析查詢的查詢解析器。”
- “設(shè)置好之后,搜索便可以在下周按照相同的方式去搜索。”
- “同義詞簡單易用。”
- ……還有許多其他值得了解的亮點,您應(yīng)當(dāng)找來一讀!
需要注意的是,搜索有許多的挑戰(zhàn),而且這些挑戰(zhàn)不僅僅在幕后。您需要思考如何管理狀態(tài),構(gòu)建用于篩選、分面、排序、分頁、同義詞、語言處理的組件,以及更多其他方面的事情。但是,總而言之:
構(gòu)建優(yōu)異的搜索需要經(jīng)過兩個復(fù)雜的部分:(1) 搜索引擎,它提供支持搜索的 API;(2) 搜索庫,它豐富搜索體驗。
關(guān)于搜索引擎,我們將基于 Elastic 應(yīng)用搜索進(jìn)行介紹。
關(guān)于搜索體驗,我們將介紹 OS 搜索庫:Search UI。
當(dāng)我們完成時,將生成類似以下所示的頁面
搜索引擎:Elastic 應(yīng)用搜索
Elastic 應(yīng)用搜索可作為一項付費的托管服務(wù)或免費的自管型分發(fā)提供。在本教程中,我們將使用托管服務(wù),但請記住,如果您自己托管的話,您的團隊可以通過基本許可_免費_使用 Search UI 和應(yīng)用搜索。
計劃:將代表有史以來最好的電子游戲的文檔索引到搜索引擎中,然后設(shè)計并優(yōu)化搜索體驗,以搜索它們。
首先,注冊以獲得 14 天的試用期 — 不需要信用卡。
創(chuàng)建一個引擎。有 13 種不同的語言可供選擇。
我們將它命名為 video-games,并將語言設(shè)為 English(英語)。
下載 best video games data set(最佳電子游戲數(shù)據(jù)集),然后使用導(dǎo)入程序?qū)⑵渖蟼鞯綉?yīng)用搜索。
接下來,單擊“Engine”(引擎),然后選擇 Credentials(憑據(jù))選項卡。
創(chuàng)建一個新的具有有限引擎訪問權(quán)限的公共搜索密鑰,以只能訪問 video-games 引擎。
檢索這個新的公共搜索密鑰和您的主機標(biāo)識符。
雖然看起來不怎么樣,但我們現(xiàn)在有了一個功能齊全的搜索引擎,可以使用優(yōu)化的搜索 API 來搜索我們的電子游戲數(shù)據(jù)了。
下列是截止現(xiàn)在我們已完成的操作:
- 創(chuàng)建了搜索引擎
- 采集了文檔
- 創(chuàng)建了默認(rèn)架構(gòu)
- 檢索了可公開給瀏覽器的、限定范圍的一次性憑據(jù)
這些是截至現(xiàn)在針對應(yīng)用搜索所做的操作。
下面我們使用 Search UI 開始構(gòu)建搜索體驗。
搜索庫:Search UI
我們將使用 create-react-app 支架實用工具來創(chuàng)建 React 應(yīng)用:
在此基礎(chǔ)上,我們將安裝 Search UI 和應(yīng)用搜索連接器:
在開發(fā)模式下啟動應(yīng)用:
使用您喜愛的文本編輯器打開 src/App.js。
我們將從一些樣本代碼開始入手,將其解包。
注意備注!
第 1 步:導(dǎo)入語句
我們需要導(dǎo)入 Search UI 依賴項和 React。
核心組件、連接器和視圖組件包含在三個不同的包中:
- @elastic/search-ui-app-search-connector
- @elastic/react-search-ui
- @elastic/react-search-ui-views
隨著課程的進(jìn)行,我們將了解每個包的更多信息。
此外,我們還將為這個項目導(dǎo)入默認(rèn)樣式表,這樣我們無需編寫自己的 CSS 行便可獲得良好的外觀和感覺:
第 2 步:連接器
我們從應(yīng)用搜索獲取了公共搜索密鑰和主機標(biāo)識符。
現(xiàn)在是使用它們的時候了!
Search UI 中的連接器對象使用憑據(jù)與應(yīng)用搜索掛鉤并支持搜索:
Search UI 可與任何搜索 API 協(xié)同工作。但是有了連接器,搜索 API 不需要任何更深層配置,便可以正常工作。
第 3 步:configurationOptions
在深入探討 configurationOptions 之前,我們花點時間認(rèn)真思考一下。
我們將一組數(shù)據(jù)導(dǎo)入了搜索引擎。但是,這是什么樣的數(shù)據(jù)呢?
我們對數(shù)據(jù)了解越多,就越能知道如何將數(shù)據(jù)提供給搜索人員,并能知曉如何配置搜索體驗。
讓我們看一個對象,它是這個數(shù)據(jù)集中最好的對象:
We see that it has several text fields like name, year, platform, and so on and some number fields like critic_score, global_sales, and user_score.
If we ask three key questions, we’ll know enough to build a solid search experience:
- How will most people search?By the name of the video game.
- What will most people want to see in a result?The name of the video game, its genre, publisher, scores, and its platform.
- How will most people filter, sort, and facet?By score, genre, publisher, and platform.
We then can translate those answers into our configurationOptions:
我們已將 Search UI 連接到搜索引擎,接下來選擇管理搜索數(shù)據(jù)、顯示結(jié)果和瀏覽結(jié)果的方式。但是,我們需要一些東西將所有內(nèi)容與 Search UI 的動態(tài)前端組件聯(lián)系起來。
第 4 步:SearchProvider
這是控制所有內(nèi)容的對象。SearchProvider 是嵌套所有其他組件的位置。
Search UI 提供了 Layout 組件,用于繪制典型的搜索布局。另有一些深入定制選項,但我們在此教程中不做深入介紹。
我們將做兩件事情:
- 將 configurationOptions 傳入 SearchProvider。
- 將一些結(jié)構(gòu)構(gòu)建塊放入 Layout,并添加兩個基本組件:SearchBox 和 Results。
目前,我們已在前端完成基本設(shè)置工作。后端還有一些額外細(xì)節(jié)需要處理,然后我們才能運行。我們還應(yīng)該研究相關(guān)度模型,以便根據(jù)這個項目的獨特需求對搜索進(jìn)行微調(diào)。
退出到應(yīng)用搜索……
回到實驗室
應(yīng)用搜索具有強大而優(yōu)化的搜索引擎功能,能夠使一度復(fù)雜的調(diào)整變得更加有趣。通過幾次單擊,便可以執(zhí)行精細(xì)的相關(guān)度調(diào)整和無縫架構(gòu)更改。
我們將首先調(diào)整架構(gòu)來查看它的實際情況。
登錄應(yīng)用搜索引擎,然后單擊 Manage(管理)部分下的 Schema(架構(gòu))。
此時將顯示架構(gòu)。11 個字段中的每個字段都默認(rèn)為 text(文本)。
在 configurationOptions 對象中,我們定義了兩個范圍分面來幫助按數(shù)字搜索:user_score 和 critic_score。為了使范圍分面按預(yù)期工作,字段類型需要設(shè)為數(shù)字。
單擊每個字段旁的下拉菜單,將其改為 number(數(shù)字),然后單擊 Update Types(更新類型):
引擎即刻重新索引。稍后,當(dāng)我們將分面組件添加到布局中時,范圍篩選器將按我們預(yù)期的方式工作?,F(xiàn)在,看看真正實用的功能。
本部分非常重要
有三個關(guān)鍵的相關(guān)度功能:同義詞、管理和相關(guān)度調(diào)整。
選擇側(cè)欄中 Search Settings(搜索設(shè)置)部分下的每項功能:
同義詞
有些人開轎車,有些人開汽車,有些人可能開老爺車。互聯(lián)網(wǎng)是全球性的,世界各地的人們用不同的詞語來描述事物。同義詞可幫助您創(chuàng)建一組被認(rèn)為是相同的術(shù)語。
在電子游戲搜索引擎案例中,我們知道人們想要查找 Final Fantasy。但他們可能只鍵入 FF。
單擊 Synonyms(同義詞),選擇 Create a Synonym Set(創(chuàng)建同義詞集),然后輸入這些術(shù)語:
單擊 Save(保存)。您可以根據(jù)需要添加任意數(shù)量的同義詞集。
現(xiàn)在,搜索 FF 將與搜索 Final Fantasy 具有相同的權(quán)重。
管理
管理是最受歡迎的功能。如果某人搜索 Final Fantasy 或 FF,結(jié)果會怎樣呢?這個系列中有很多游戲,他們會獲得哪個結(jié)果呢?
默認(rèn)情況下,排列前五的結(jié)果將如下顯示:
1.Final Fantasy VIII
2.Final Fantasy X
3.Final Fantasy Tactics
4.Final Fantasy IX
5.Final Fantasy XIII
這好像不對,F(xiàn)inal Fantasy VII 才是 Final Fantasy 中最佳的一款游戲,而且 Final Fantasy XIII 不是很好的游戲! 😜
我們是否可以讓搜索 Final Fantasy 的人們看到 Final Fantasy VII 列在第一位?是否可以從結(jié)果中刪除 Final Fantasy XIII?
我們能做到!
單擊 Curations(管理),輸入查詢:Final Fantasy。
接下來,通過按住表最左側(cè)的把手,將 Final Fantasy VII 文檔向上拖動到 Promoted Documents(提升的文檔)部分。然后,單擊 Final Fantasy XIII 文檔上的 Hide Result(隱藏結(jié)果)按鈕 — 帶貫穿線的眼睛圖標(biāo):
現(xiàn)在,搜索 Final Fantasy 或 FF 將會看到 Final Fantasy VII 排在首位,
并且根本看不到 Final Fantasy XIII 了。哈哈!
我們可以提升和隱藏多個文檔。我們甚至可以對提升的文檔進(jìn)行排序,以便完全控制每個查詢頂部顯示的內(nèi)容。
相關(guān)度調(diào)整
單擊側(cè)欄中的 Relevance Tuning(相關(guān)度調(diào)整)。
我們搜索一個文本字段:name 字段。但是,如果我們擁有多個要搜索的文本字段(例如 name 字段和 description 字段),該怎么辦?我們使用的電子游戲數(shù)據(jù)集不包含 description 字段,因此,我們將偽造一些文檔來仔細(xì)考慮這個字段。
假設(shè)文檔類似如下:
如果某人想要查找游戲 Magical Quest,則會輸入它作為查詢。但是,第一個結(jié)果將是 Dangerous Quest:
為什么會這樣?這是因為“magical”一詞在 Dangerous Quest 的描述中出現(xiàn)了三次,搜索引擎不知道這個字段比另一個字段更重要。于是,它將 Dangerous Quest 排得更靠前。這就是要進(jìn)行相關(guān)度調(diào)整的原因。
我們可以在其他內(nèi)容中選擇一個字段,然后提高其相關(guān)度權(quán)重:
我們可以看到,在提高權(quán)重后,正確的項 Magical Quest 上升到頂部,因為 name 字段變得更重要。我們要做的就是將滑塊拖動到更高值,然后單擊 Save(保存)。
現(xiàn)在,我們使用應(yīng)用搜索執(zhí)行下列操作:
- 調(diào)整架構(gòu),將 user_score 和 critic_score 更改為 number 字段。
- 精細(xì)調(diào)整相關(guān)度模型。
至此,我們就介紹完了這些巧妙而先進(jìn)的“儀表板”功能 — 每項功能都有匹配的 API 端點,如果您不喜歡 GUI,則可以使用 API 端點以編程方式運行各功能。
現(xiàn)在,讓我們完成 Search UI 的介紹。
收尾工作
現(xiàn)在,您的 UI 應(yīng)該可以正常運行了。嘗試進(jìn)行一些查詢,看看結(jié)果如何。首先,我們?nèi)鄙僖恍┕ぞ邅硖剿魑覀兊慕Y(jié)果,例如,篩選、分面、排序等等,但是可以搜索了。我們需要充實 UI。
在初始 src/App.js 文件中,我們導(dǎo)入了三個基本組件:
根據(jù)我們對配置選項定義的內(nèi)容,讓我們再添加一些組件。
導(dǎo)入以下組件將會啟用 UI 中缺失的功能:
- PagingInfo:在當(dāng)前頁面上顯示信息。
- ResultsPerPage:配置在每一個頁面上顯示的結(jié)果數(shù)。
- Paging:導(dǎo)航不同的頁面。
- Facet:以數(shù)據(jù)類型特有的方式篩選和瀏覽數(shù)據(jù)。
- Sorting:重新排定給定字段的結(jié)果。
導(dǎo)入后,組件可以放入到 Layout 中。
Layout 組件將頁面分為多個部分,各組件可以通過屬性放入這些部分中。
它包含以下部分:
- Header:搜索框/搜索欄
- bodyContent:結(jié)果容器
- sideContent:側(cè)欄,其中包含分面和排序選項
- bodyHeader:圍繞結(jié)果包含了上下文豐富的信息,例如當(dāng)前頁面和每一頁面上的結(jié)果數(shù)量
- bodyFooter:用于在頁面之間快速導(dǎo)航的分頁選項
組件呈現(xiàn)數(shù)據(jù)。數(shù)據(jù)是根據(jù)我們在 configurationOptions 中提供的搜索設(shè)置進(jìn)行獲取的?,F(xiàn)在,我們將每個組件放入相應(yīng)的 Layout 部分。
例如,我們在 configurationOptions 中描述了五個分面維度,因此,我們將創(chuàng)建五個 Facet 組件。每個 Facet 組件都將使用一個“field”屬性作為返回數(shù)據(jù)的鍵。
我們將它們以及 Sorting 組件放入 sideContent 部分中,然后將 Paging、PagingInfo 和 ResultsPerPage 組件放入最適合它們的部分中:
現(xiàn)在,讓我們看一下本地開發(fā)環(huán)境中的搜索體驗。
好多了!我們有了很多選項來瀏覽搜索結(jié)果。
我們添加了一些額外功能,例如,多個排序選項,并且通過添加單一標(biāo)志使得發(fā)布者分面可篩選。嘗試使用一個空查詢進(jìn)行搜索,從而瀏覽所有選項。
最后,我們看一下搜索體驗的最后一個功能。它就是受歡迎的
“自動完成”功能。
自動完成
搜索人員喜歡自動完成,因為它可以提供即時反饋。它的建議有兩種方式:結(jié)果和查詢。根據(jù)方式的不同,搜索人員將收到相關(guān)結(jié)果或生成結(jié)果的潛在查詢。
我們將重點介紹自動完成的查詢建議形式。
這需要做兩項快速更改。
首先,需要將自動完成添加到 configurationOptions 對象:
其次,需要將自動完成作為 SearchBox 的一個函數(shù)啟用:
好了,就這么簡單。
嘗試搜索一下。當(dāng)您鍵入時,將顯示自動完成查詢建議。
總結(jié)
現(xiàn)在,我們擁有了外觀好看、功能完善的搜索體驗,而且還避免了一大堆人們在嘗試實施搜索時會掉入的陷阱。30 分鐘的講解還不錯,是不是?
Search UI是靈活的現(xiàn)代 React 框架,可用于快速開發(fā)搜索體驗。Elastic 應(yīng)用搜索是 Elasticsearch 中內(nèi)置的強大搜索引擎。這是一項付費的托管服務(wù),或者通過一個足夠用的基本許可,您也可以免費運行它。