Supabase の全文検索を試してみた

西田@MADです 今回は Supabase の全文検索を試してみました
2022.08.12

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

西田@MADです

今回は Supabase の全文検索を試してみました

Supabaseの基本的な使い方は以下の記事を参考にしてください

オープンソースで話題のBaaS「Supabase」を使ってみた

動くサンプルを作成してますので、こちらもご参考ください

今回知りたいこと

  • Next.js で Supabase の全文検索の使い方
  • 複数列を対象に検索できるか
  • 日本語を全文検索できるか
  • 料金

結論から

  • Next.js で Supabase の全文検索の使い方
    • 本文を参照
  • 複数列を対象に検索できるか
    • Database API を作成すれば可能
  • 日本語を全文検索できるか
    • 執筆時点では使えない
  • 料金
    • 全文検索の使用有無による料金の違いはなし

Next.js で Supabase の全文検索の使い方

Supabase を Next.js で使用する準備

Settings > API のURLとAPI Keys をメモし

.env.local ファイルに Supabase に接続するための情報を書きます

NEXT_PUBLIC_SUPABASE_URL=https://xxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=xxxx

SupabaseのSDKインストール

# ライブラリインストール
$ yarn add @supabase/supabase-js

クライアントを作成

import { createClient } from "@supabase/supabase-js";

const NEXT_PUBLIC_SUPABASE_URL = process.env.NEXT_PUBLIC_SUPABASE_URL;
const NEXT_PUBLIC_SUPABASE_ANON_KEY = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;

if (!NEXT_PUBLIC_SUPABASE_URL || !NEXT_PUBLIC_SUPABASE_ANON_KEY) {
  throw new Error("Must be specified supabase settings in env");
}
const client = createClient(
  NEXT_PUBLIC_SUPABASE_URL,
  NEXT_PUBLIC_SUPABASE_ANON_KEY
);

検索機能

Supabase の全文検索はJSのみで完結する機能と、Database Functions + RPC(API)を使わないと実現できない機能があります

JS のみで完結できる機能

JS からは textSearch メソッドで全文検索を行います

単一の列、単一のキーワードで検索します

const { data, error } = client
    .from("manuals")
    .select()
    .textSearch("summary", `'${keyword}'`);

AND(すべてのキーワードを含む)検索は & でキーワードを連結します

const { data, error } = client
    .from("manuals")
    .select()
    .textSearch("summary", `'${keyword1}' & '${keyword2}'`);

OR(いずれかのキーワードを含む)検索は | でキーワードを連結します

const { data, error } = client
    .from("manuals")
    .select()
    .textSearch("summary", `'${keyword1}' | '${keyword2}'`);

スペース区切りのキーワードをAND検索のサンプルです

const queryKeyword = keyword
      .split(/\s+/)
      .map((word) => `'${word}' & `)
      .join("")
      .slice(0, -3);

query = query.textSearch("summary", queryKeyword);
const { data, error } = await query;

複数列を対象に検索できるか

Database Functions + RPC

複数列を対象に全文検索するにはDatabase Funtions を作成し、JSからはRPCを使って作成したDatabase Funtions を呼び出す必要があります

Database Functions を作成

create or replace function search_manuals(keyword text)
returns setof manuals -- 返却データの種類
language sql -- 使用する言語
as $$ -- 関数
  select * 
  from manuals 
  where to_tsvector(title || ' ' || summary) @@ to_tsquery(keyword);
$$;

JSからrpcで呼び出し

const { data, error } = await client.rpc("search_manuals", { keyword });

Database Functions の中で以下の関数を利用して全文検索を行ってます

to_tsvector(to text search vector)

全文検索用のデータに変換する関数

to_tsquery (to text search query)

全文検索用のデータに問い合わせ用のデータに変換する関数

日本語を全文検索できるか

textSearch メソッドに config パラメーターがあり、言語を指定できるようですが、執筆時点で japanese はまだ非対応のようでした

{
  code: '42704',
  details: null,
  hint: null,
  message: 'text search configuration "japanese" does not exist'
}

また、Supabase で、今使える PostgreSQL の extension の中に日本語の全文検索に対応できるものはなさそうでした

https://www.supabase.jp/docs/guides/database/extensions

対応されるのを楽しみにまちたいと思います

料金

料金ページを見る限り、全文検索の使用の有無で料金がかわることはなさそうです 

Pricing & fees | Supabase

参考

全文検索 | Supabase

How to use textSearch to perform full text search - SupabaseTips - YouTube