一個適配器,用於將很棒的 Instantsearch.js 庫與 Typesense 搜尋伺服器結合使用,以建立豐富的搜尋介面。
以下是您可以使用此適配器建立的 UI 範例:songs-search.typesense.org
注意:如果您的搜尋介面是基於自訂自動完成元件建立的,或者基於 @algolia/autocomplete-js,那麼您不需要此適配器將其與 Typesense 一起使用,因為 typesense-js 庫已經支援客戶端獲取來自任何非同步資料來源的資料。在這裡閱讀更多內容。
Algolia 的優秀人員建立並開源了 Instantsearch.js,它是一組開箱即用的元件,您可以使用它們快速建立互動式搜尋體驗。
借助此儲存庫中的適配器,您將能夠使用 Instantsearch(及其 React、Vue 和 Angular 同類產品)以及 Typesense 搜尋伺服器中索引的資料。
如果您以前沒有使用過 Instantsearch,我們建議您在此處閱讀他們的入門指南。閱讀完本指南後,請按照以下說明將 Typesense 適配器插入 Instantsearch。
以下是使用 Typesense 和 InstantSearch.js 建立快速搜尋介面的指南:https://typesense.org/docs/0.20.0/guide/search-ui-components.html
這是一個示範入門應用程序,向您展示如何使用適配器:https://github.com/typesense/typesense-instantsearch-demo
$ npm install --save typesense-instantsearch-adapter @babel/runtime
或者
$ yarn add typesense-instantsearch-adapter @babel/runtime
或者,您也可以透過 HTML 中的腳本標記直接包含適配器:
< script src =" https://cdn.jsdelivr.net/npm/typesense-instantsearch-adapter@2/dist/typesense-instantsearch-adapter.min.js " > </ script >
<!-- You might want to pin the version of the adapter used if you don't want to always receive the latest minor version -->
由於這是一個適配器,它不會自動為您安裝Instantsearch 庫。您需要直接在應用程式中安裝以下其中一項:
您將在上述每個庫各自的儲存庫中找到有關如何開始使用它們的資訊。
我們也建議您查看 create-instantsearch-app 以從入門範本建立您的搜尋 UI。
import instantsearch from "instantsearch.js" ;
import { searchBox , hits } from "instantsearch.js/es/widgets" ;
import TypesenseInstantSearchAdapter from "typesense-instantsearch-adapter" ;
const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter ( {
server : {
apiKey : "abcd" , // Be sure to use an API key that only allows search operations
nodes : [
{
host : "localhost" ,
path : "" , // Optional. Example: If you have your typesense mounted in localhost:8108/typesense, path should be equal to '/typesense'
port : "8108" ,
protocol : "http" ,
} ,
] ,
cacheSearchResultsForSeconds : 2 * 60 , // Cache search results from server. Defaults to 2 minutes. Set to 0 to disable caching.
} ,
// The following parameters are directly passed to Typesense's search API endpoint.
// So you can pass any parameters supported by the search endpoint below.
// query_by is required.
additionalSearchParameters : {
query_by : "name,description,categories" ,
} ,
} ) ;
const searchClient = typesenseInstantsearchAdapter . searchClient ;
const search = instantsearch ( {
searchClient ,
indexName : "products" ,
} ) ;
search . addWidgets ( [
searchBox ( {
container : "#searchbox" ,
} ) ,
hits ( {
container : "#hits" ,
templates : {
item : `
<div class="hit-name">
{{#helpers.highlight}}{ "attribute": "name" }{{/helpers.highlight}}
</div>
` ,
} ,
} ) ,
] ) ;
search . start ( ) ;
您可以在此處新增適配器支援的任何 Instantsearch 小工具。
您也可以在 test/support/testground 中找到一個工作範例。要運行它,請從專案根資料夾執行npm run testground
。
import React from "react" ;
import ReactDOM from "react-dom" ;
import { SearchBox } from "react-instantsearch-dom" ;
import TypesenseInstantSearchAdapter from "typesense-instantsearch-adapter" ;
const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter ( {
server : {
apiKey : "abcd" , // Be sure to use an API key that only allows search operations
nodes : [
{
host : "localhost" ,
port : "8108" ,
path : "" , // Optional. Example: If you have your typesense mounted in localhost:8108/typesense, path should be equal to '/typesense'
protocol : "http" ,
} ,
] ,
cacheSearchResultsForSeconds : 2 * 60 , // Cache search results from server. Defaults to 2 minutes. Set to 0 to disable caching.
} ,
// The following parameters are directly passed to Typesense's search API endpoint.
// So you can pass any parameters supported by the search endpoint below.
// query_by is required.
additionalSearchParameters : {
query_by : "name,description,categories" ,
} ,
} ) ;
const searchClient = typesenseInstantsearchAdapter . searchClient ;
const App = ( ) => (
< InstantSearch indexName = "products" searchClient = { searchClient } >
< SearchBox / >
< Hits / >
< / InstantSearch >
) ;
然後,您可以在此處新增適配器支援的任何 Instantsearch-React 小工具。
上述說明也適用於 React Native。
應用程式.vue:
< template >
< ais-instant-search :search-client = " searchClient " index-name = " products " >
< ais-search-box />
< ais-hits >
< div slot = " item " slot-scope = " { item } " >
< h2 >{{ item.name }}</ h2 >
</ div >
</ ais-hits >
</ ais-instant-search >
</ template >
< script >
import TypesenseInstantSearchAdapter from " typesense-instantsearch-adapter " ;
const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter ({
server : {
apiKey : " abcd " , // Be sure to use an API key that only allows search operations
nodes : [
{
host : " localhost " ,
path : " " , // Optional. Example: If you have your typesense mounted in localhost:8108/typesense, path should be equal to '/typesense'
port : " 8108 " ,
protocol : " http " ,
},
],
cacheSearchResultsForSeconds : 2 * 60 , // Cache search results from server. Defaults to 2 minutes. Set to 0 to disable caching.
},
// The following parameters are directly passed to Typesense's search API endpoint.
// So you can pass any parameters supported by the search endpoint below.
// query_by is required.
additionalSearchParameters : {
query_by : " name,description,categories " ,
},
});
const searchClient = typesenseInstantsearchAdapter . searchClient ;
export default {
data () {
return {
searchClient,
};
},
};
</ script >
然後,您可以在此處新增適配器支援的任何 Instantsearch 小工具。
// app.component.ts
import { Component } from "@angular/core" ;
import TypesenseInstantSearchAdapter from "typesense-instantsearch-adapter" ;
const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter ( {
server : {
apiKey : "abcd" , // Be sure to use an API key that only allows search operations
nodes : [
{
host : "localhost" ,
path : "" , // Optional. Example: If you have your typesense mounted in localhost:8108/typesense, path should be equal to '/typesense'
port : "8108" ,
protocol : "http" ,
} ,
] ,
cacheSearchResultsForSeconds : 2 * 60 , // Cache search results from server. Defaults to 2 minutes. Set to 0 to disable caching.
} ,
// The following parameters are directly passed to Typesense's search API endpoint.
// So you can pass any parameters supported by the search endpoint below.
// query_by is required.
additionalSearchParameters : {
query_by : "name,description,categories" ,
} ,
} ) ;
const searchClient = typesenseInstantsearchAdapter . searchClient ;
@ Component ( {
selector : "app-root" ,
templateUrl : "./app.component.html" ,
styleUrls : [ "./app.component.css" ] ,
} )
export class AppComponent {
config = {
indexName : "products" ,
searchClient ,
} ;
}
然後,您可以在此處新增適配器支援的任何 Instantsearch 小工具。
hierarchicalMenu
對於此小工具,您希望使用下列特定命名約定在集合架構中建立獨立欄位:
field.lvl0
field.lvl1
field.lvl2
對於field.lvl0 > field.lvl1 > field.lvl2
的嵌套層次結構
每個欄位還可以保存一個值數組。這對於處理多個層次結構很有用。
sortBy
實例化此小工具時,您需要將索引名稱的值設定為以下特定格式:
search . addWidgets ( [
sortBy ( {
container : "#sort-by" ,
items : [
{ label : "Default" , value : "products" } ,
{ label : "Price (asc)" , value : "products/sort/price:asc" } ,
{ label : "Price (desc)" , value : "products/sort/price:desc" } ,
] ,
} ) ,
] ) ;
value 屬性的一般模式為: <index_name>[/sort/<sort_by>]
。適配器將使用<sort_by>
中的值作為sort_by
搜尋參數的值。
configure
如果您需要為 Typesense 指定一個filter_by
搜尋參數,您需要使用configure
InstantSearch 小工具以及facetFilters
、 numericFilters
或filters
。
facetFilters
和numericFilters
的格式與 Algolia 的格式相同,如這裡所述。但filters
需要採用 Typesense 的filter_by
格式,如此表所述。
只有在最初載入小工具時,在additionalQueryParameters
配置中設定filter_by
才有效,因為InstantSearch 隨後會在內部覆寫filter_by
欄位。在這裡閱讀更多內容。
index
對於聯合/多索引搜索,您需要使用index
小工具。為了能夠為每個索引/集合指定不同的搜尋參數,您可以使用collectionSpecificSearchParameters
配置來指定它們:
const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter ( {
server : {
apiKey : "abcd" , // Be sure to use an API key that only allows search operations
nodes : [ { host : "localhost" , path : "/" , port : "8108" , protocol : "http" } ] ,
} ,
// Search parameters that are common to all collections/indices go here:
additionalSearchParameters : {
numTypos : 3 ,
} ,
// Search parameters that need to be *overridden* on a per-collection-basis go here:
collectionSpecificSearchParameters : {
products : {
query_by : "name,description,categories" ,
} ,
brands : {
query_by : "name" ,
} ,
} ,
} ) ;
const searchClient = typesenseInstantsearchAdapter . searchClient ;
本質上,在查詢 Typesense 時, collectionSpecificSearchParameters
中設定的任何參數都會與additionalSearchParameters
中的值合併,從而有效地基於每個集合覆蓋additionalSearchParameters
中的值。
geoSearch
Algolia 預設使用_geoloc
作為儲存記錄的經緯度值的欄位名稱。在 Typesense 中,您可以將地理位置欄位命名為任何名稱。如果您使用_geoloc
以外的名稱,則需要在初始化適配器時指定它,如下所示,以便 InstantSearch 可以存取它:
const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter ( {
server : {
apiKey : "xyz" ,
nodes : [
{
host : "localhost" ,
port : "8108" ,
path : "/" ,
protocol : "http" ,
} ,
] ,
} ,
geoLocationField : "lat_lng_field" , // <<======
additionalSearchParameters ,
} ) ;
dynamicWidgets
自 Typesense Server
v0.25.0.rc12
起可用
這個dynamicWidgets
小工具開箱即用,無需額外更改,但如果您想控制這些方面在UI中顯示的順序,Instantsearch需要設定一個名為renderingContent
的參數。
const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter ( {
server : {
apiKey : "xyz" ,
nodes : [
{
host : "localhost" ,
port : "8108" ,
path : "/" ,
protocol : "http" ,
} ,
] ,
} ,
renderingContent : {
// <<===== Add this, only if you want to control the order of the widgets displayed by dynamicWidgets
facetOrdering : {
facets : {
order : [ "size" , "brand" ] , // <<===== Change this as needed
} ,
} ,
} ,
additionalSearchParameters ,
} ) ;
請在此處閱讀 Algolia 文件中有關renderingContent
的所有可用選項的更多資訊。
自 typesense-instantsearch-adapter
2.7.0-2
起可用
如果文件中的任何字串字段的值中有一個冒號:
(例如,假設有一個名為{ brand: "a:b" }
字段,那麼在實例化適配器時,您需要添加以下參數:
const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter ( {
server : {
apiKey : "xyz" ,
nodes : [
{
host : "localhost" ,
port : "8108" ,
path : "/" ,
protocol : "http" ,
} ,
] ,
} ,
facetableFieldsWithSpecialCharacters : [ "brand" ] , // <======= Add string fields that have colons in their values here, to aid in parsing
additionalSearchParameters ,
} ) ;
如果文件中的任何數字字段名稱具有特殊字符,例如>
、 <
、 =
(例如,假設有一個名為{ price>discount: 3.0 }
的字段),那麼在實例化適配器時,您需要添加以下參數:
const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter ( {
server : {
apiKey : "xyz" ,
nodes : [
{
host : "localhost" ,
port : "8108" ,
path : "/" ,
protocol : "http" ,
} ,
] ,
} ,
facetableFieldsWithSpecialCharacters : [ "price>discount" ] , // // <======= Add numeric fields that have >, < or = in their names, to aid in parsing
additionalSearchParameters ,
} ) ;
facet_by
選項從 typesense-instantsearch-adapter
2.8.0-1
和 Typesense Serverv0.26.0.rc25
開始可用
當您使用各種篩選器小工具時, facet_by
參數由 InstantSearch 在內部管理。
但是如果您需要將自訂選項傳遞給facet_by
參數(例如:伺服器端排序選項),那麼您可以使用facetByOptions
參數,如下所示:
const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter ( {
server : {
apiKey : "xyz" ,
nodes : [
{
host : "localhost" ,
port : "8108" ,
path : "/" ,
protocol : "http" ,
} ,
] ,
} ,
facetByOptions : {
brand : "(sort_by: _alpha:asc)" ,
category : "(sort_by: _alpha:desc)" ,
} , // <======= Add any facet_by parameter as a key value pair. Don't forget the surrounding parantheses in the value.
collectionSpecificFacetByOptions : {
collection1 : {
brand : "(sort_by: _alpha:desc)" ,
} ,
} , // <======= Use this parameter if multiple collections share the same field names, and you want to use different options for each field. This will override facetByOptions for that particular collection.
additionalSearchParameters ,
} ) ;
請注意,為了在refinementLists中進行排序,除了在Typesense伺服器端進行排序之外,您還需要將sortBy
參數傳遞給refinementList小工具,以便在客戶端對結果進行適當的排序。
filter_by
選項自 typesense-instantsearch-adapter
2.8.0-5
起可用
當您使用各種濾鏡小工具時, filter_by
參數由 InstantSearch 在內部管理。
預設情況下,適配器在將查詢傳送到 Typesense 時使用精確過濾 ( filter_by: field:=value
)。如果需要將適配器配置為使用:
(非精確字級過濾 - filter_by: field:value
),則需要使用filterByOptions
配置實例化適配器:
const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter ( {
server : {
apiKey : "xyz" ,
nodes : [
{
host : "localhost" ,
port : "8108" ,
path : "/" ,
protocol : "http" ,
} ,
] ,
} ,
filterByOptions : {
brand : { exactMatch : false } , // <========== Add this to do non-exact word-level filtering
category : { exactMatch : false } ,
} ,
collectionSpecificFilterByOptions : {
collection1 : {
brand : { exactMatch : false } ,
} ,
} , // <======= Use this parameter if multiple collections share the same field names, and you want to use different options for each field. This will override filterByOptions for that particular collection.
additionalSearchParameters ,
} ) ;
自 typesense-instantsearch-adapter
2.9.0-0
起可用
當使用者選擇特定排序順序時,以下是停用覆蓋/管理規則的方法:
const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter ( {
server : {
apiKey : "xyz" ,
nodes : [
{
host : "localhost" ,
port : "8108" ,
path : "/" ,
protocol : "http" ,
} ,
] ,
} ,
sortByOptions : {
"field1:desc,field2:desc" : { enable_overrides : false } , // <========== Add this to disable sorting when this particular Typesense `sort_by` string is generated by the sortBy widget
} ,
collectionSpecificSortByOptions : {
collection2 : {
"field1:desc,field2:desc" : { enable_overrides : false } ,
} ,
} , // <======= Use this parameter if multiple collections share the same field names, and you want to use different options for each field. This will override sortByOptions for that particular collection.
additionalSearchParameters ,
} ) ;
例如,如果您有一個 sortBy 小工具配置了 indexName 值products/sort/price:asc
,那麼sortByOptions
中的鍵應該是price:asc
。
從 typesense-instantsearch-adapter
2.7.1-4
開始可用
預設情況下,當使用group_by
作為搜尋參數時,適配器會將所有群組的結果展平為單一連續命中清單。
如果您想要保留群組,則需要在實例化適配器時設定flattenGroupedHits: false
。
這會將群組中的第一個命中作為主要命中,然後將群組中的所有命中添加到每個命中內的_grouped_hits
鍵內。
const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter ( {
server : {
apiKey : "xyz" ,
nodes : [
{
host : "localhost" ,
port : "8108" ,
path : "/" ,
protocol : "http" ,
} ,
] ,
} ,
flattenGroupedHits : false , // <=======
additionalSearchParameters ,
} ) ;
自 typesense-instantsearch-adapter
2.7.0-3
起可用
整體想法是首先掛鉤 Instantsearch 的查詢生命週期,攔截類型化查詢並將其發送到嵌入 API,獲取嵌入,然後將向量發送到 Typesense 進行最近鄰向量搜尋。
這是一個演示,您可以在本地運行以查看其實際效果:https://github.com/typesense/showcase-hn-comments-semantic-search。
以下是在 Instantsearch.js 中執行此操作的方法:
const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter ( {
server : {
apiKey : "xyz" ,
nodes : [
{
host : "localhost" ,
port : "8108" ,
path : "/" ,
protocol : "http" ,
} ,
] ,
} ,
additionalSearchParameters ,
} ) ;
// from https://github.com/typesense/showcase-hn-comments-semantic-search/blob/8a33006cae58b425c53f56a64e1273e808cd9375/src/js/index.js#L101
const searchClient = typesenseInstantsearchAdapter . searchClient ;
search = instantsearch ( {
searchClient ,
indexName : INDEX_NAME ,
routing : true ,
async searchFunction ( helper ) {
// This fetches 200 (nearest neighbor) results for semantic / hybrid search
let query = helper . getQuery ( ) . query ;
const page = helper . getPage ( ) ; // Retrieve the current page
if ( query !== "" && [ "semantic" , "hybrid" ] . includes ( $ ( "#search-type-select" ) . val ( ) ) ) {
console . log ( helper . getQuery ( ) . query ) ;
helper
. setQueryParameter (
"typesenseVectorQuery" , // <=== Special parameter that only works in [email protected] and above
`embedding:([], k:200)` ,
)
. setPage ( page )
. search ( ) ;
console . log ( helper . getQuery ( ) . query ) ;
} else {
helper . setQueryParameter ( "typesenseVectorQuery" , null ) . setPage ( page ) . search ( ) ;
}
} ,
} ) ;
快取有兩種模式:
伺服器端緩存:
若要啟用伺服器端緩存,請在 typesense-instantsearch-adapter 的server
設定區塊中新增一個名為useServerSideSearchCache: true
的參數,如下所示:
const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter ( {
server : {
apiKey : "..." ,
nearestNode : { ... } ,
nodes : [ ... ] ,
useServerSideSearchCache : true // <<< Add this to send use_cache as a query parameter instead of post body parameter
} ,
additionalSearchParameters : { ... }
} ) ;
這將導致適配器將?use_cache=true
作為 URL 查詢參數新增至適配器發起的所有搜尋請求,然後這將導致 Typesense Server 為這些請求啟用伺服器端快取。
客戶端快取:
此適配器還預設啟用客戶端快取,以防止對伺服器進行不必要的網路呼叫。客戶端快取的 TTL 可以這樣配置:
const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter ( {
server : {
apiKey : "..." ,
nearestNode : { ... } ,
nodes : [ ... ] ,
cacheSearchResultsForSeconds : 2 * 60 // <<< Add this to configure the TTL for client-side cache in the browser
} ,
additionalSearchParameters : { ... }
} ) ;
類型感應伺服器 | typesense-instantsearch-適配器 | 即時搜尋.js | 反應即時搜尋 | vue-即時搜尋 | 角度即時搜尋 |
---|---|---|---|---|---|
>= v0.25.0 | >= v2.7.1 | >= 4.51 | >= 6.39 | >= 4.8 | >= 4.4 |
>= v0.25.0.rc14 | >= v2.7.0-1 | >= 4.51 | >= 6.39 | >= 4.8 | >= 4.4 |
>= v0.25.0.rc12 | >= v2.6.0 | >= 4.51 | >= 6.39 | >= 4.8 | >= 4.4 |
>= v0.24 | >= v2.5.0 | >= 4.2.0 | >= 6.0.0 | >= 2.2.1 | >= 3.0.0 |
>= v0.21 | >= v2.0.0 | >= 4.2.0 | >= 6.0.0 | >= 2.2.1 | >= 3.0.0 |
>= v0.19 | >= v1.0.0 | >= 4.2.0 | >= 6.0.0 | >= 2.2.1 | >= 3.0.0 |
>= v0.15 | >= v0.3.0 | >= 4.2.0 | >= 6.0.0 | >= 2.2.1 | >= 3.0.0 |
>= v0.14 | >= v0.2.0 | >= 4.2.0 | >= 6.0.0 | >= 2.2.1 | >= 3.0.0 |
>= v0.13 | >= v0.1.0 | >= 4.2.0 | >= 6.0.0 | >= 2.2.1 | >= 3.0.0 |
>= v0.12 | >= v0.0.4 | >= 4.2.0 | >= 6.0.0 | >= 2.2.1 | >= 3.0.0 |
如果上述程式庫的特定版本不適用於該適配器,請開啟一個包含詳細資訊的 Github 問題。
此適配器適用於該清單中的所有小部件
$ npm install
$ npm run typesenseServer
$ FORCE_REINDEX=true npm run indexTestData
$ npm link typesense-instantsearch-adapter
$ npm run testground
$ npm test
要發布新版本,我們使用 np 套件:
$ npm install --global np
$ np
# Follow instructions that np shows you
如果您有任何疑問或遇到任何問題,請建立 Github 問題,我們將盡力提供協助。
© 2020 年至今 Typesense, Inc.