Typesense Search Server で素晴らしい Instantsearch.js ライブラリを使用して、リッチな検索インターフェイスを構築するためのアダプター。
このアダプターを使用して構築できる UI の例は次のとおりです: songs-search.typesense.org
注:検索インターフェイスがカスタム オートコンプリート コンポーネント上に構築されているか、@algolia/autocomplete-js に基づいている場合、typesense-js ライブラリはすでにクライアント側のフェッチをサポートしているため、Typesense で使用するためにこのアダプターは必要ありません。非同期データ ソースからのデータ。詳細はこちらをご覧ください。
Algolia の善良な人々は、インタラクティブな検索エクスペリエンスを迅速に構築するために使用できる、すぐに使用できるコンポーネントのコレクションである Instantsearch.js を構築し、オープンソース化しました。
このリポジトリのアダプターを使用すると、Typesense 検索サーバーでインデックス付けされたデータで Instantsearch (およびその React、Vue、Angular の類似品) を使用できるようになります。
これまでに 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 タグを介してアダプターを直接組み込むこともできます。
< 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 ( ) ;
アダプターでサポートされているインスタントサーチ ウィジェットをここに追加できます。
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 にも適用されます。
App.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 >
次に、アダプターでサポートされているインスタントサーチ ウィジェットのいずれかをここに追加できます。
// 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 ,
} ;
}
次に、アダプターでサポートされているインスタントサーチ ウィジェットのいずれかをここに追加できます。
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
検索パラメーターを指定する必要がある場合は、 facetFilters
、 numericFilters
、またはfilters
とともに、 configure
InstantSearch ウィジェットを使用します。
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 ;
基本的に、 collectionSpecificSearchParameters
に設定されたパラメータは、Typesense をクエリするときに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 ,
} ) ;
RefinementList で並べ替える場合は、Typesense サーバー側で並べ替えるだけでなく、クライアント側でも結果を適切に並べ替えるために、 sortBy
パラメーターを洗練リスト ウィジェットに渡す必要があることに注意してください。
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 ,
} ) ;
たとえば、 products/sort/price:asc
の IndexName 値を使用してsortBy ウィジェットが構成されている場合、 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 ( ) ;
}
} ,
} ) ;
キャッシュには 2 つのモードがあります。
サーバー側のキャッシュ:
サーバー側のキャッシュを有効にするには、次のように、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 : { ... }
} ) ;
これにより、アダプタは、アダプタによって開始されたすべての検索リクエストに URL クエリ パラメータとして?use_cache=true
追加します。これにより、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サーバー | typesense-instantsearch-adapter | インスタントサーチ.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.