GatsbyJSのブログに検索機能を実装してみる

目次
プラグイン?
検索フォームを実装するには、どうしたらいいか?
公式サイトには Search の項目に、プラグインが 3 つ表示されています。
人気なのは、Algolia なんですかね?
う〜ん、プラグインを使わない方法はないものか? と思い、調べていくと…
全文検索?
Algolia の様に全文検索した方がいいよなぁ…とは思いつつも、個人ブログだからそこまでやる必要ある? とか思ったりもするし…
全文検索するなら、graphql の body とか html に対して、検索処理を行って…という感じになりそう?
記事が増えたら、処理に時間掛かりそうだなぁ…
graphql で試してみる
{
allMarkdownRemark(filter: {frontmatter: {categories: {eq: "magical creatures"}}}) {
edges {
node {
frontmatter {
title
categories
}
}
}
}
}
ドキュメントに上記のソースが掲載されていたので、http://localhost:8000/\_\_\_graphql で以下を試してみました。
{
allMdx(filter: {frontmatter: {tags: {eq: "GatsbyJS"}}}) {
edges {
node {
frontmatter {
title
}
}
}
}
}
これを実行してみると
{
"data": {
"allMdx": {
"edges": [
{
"node": {
"frontmatter": {
"title": "Gatsbyの記事に目次を作成してみる"
}
}
},
{
"node": {
"frontmatter": {
"title": "このブログについて"
}
}
},
{
"node": {
"frontmatter": {
"title": "GatsbyJSのブログに検索機能を実装してみる"
}
}
}
]
}
},
"extensions": {}
}
こんな感じで GatsbyJS というタグがついた記事のタイトルを取得出来ました。
{
allMdx(filter: {frontmatter: {title: {eq: "GatsbyJS"}}}) {
edges {
node {
frontmatter {
title
}
}
}
}
}
次にタイトルに GatsbyJS が入っているものを取得しようとして、上記のコードを実行してみると…
{
"data": {
"allMdx": {
"edges": []
}
},
"extensions": {}
}
取得出来ない…
title ではなく summary に対して同様に試してみましたが、こちらも上手くいかず…
{
//eqだと取得出来ない(inでも同じ)
allMdx(filter: {frontmatter: {title: {eq: "GatsbyJS"}, summary: {eq: "GatsbyJS"}}}){
//neだと取得出来る
allMdx(filter: {frontmatter: {title: {ne: "GatsbyJS"}, summary: {ne: "GatsbyJS"}}}){
//ninでも取得出来る
allMdx(filter: {frontmatter: {title: {nin: "GatsbyJS"}, summary: {nin: "GatsbyJS"}}}){
edges {
node {
frontmatter {
title
}
}
}
}
}
色々試してみたら、 eq や in ではなく ne と ini を使った場合に、title と summary で値を取得出来ました。
comparator は上記のページに掲載されていますが、何故 tags の場合と同様に eq や in で取得出来ずに、 ne と nin の場合に取得出来るのかが分からず…
フォームに検索する語句が入力される度に、(graphql の)filter を使ったクエリを発行する方法は、思ったより大変そう…
別の方法を考えてみる
他の方法だと、記事内の検索されそうな語句を使って要約を用意して、それに対して検索処理を掛けたら、全文検索っぽいのが出来るんじゃない?
この方法なら全文検索より負荷は掛からなそうだし…
---
title: "GatsbyJSのブログに検索機能を実装してみる"
date: "2022-06-17T11:15:00.000Z"
summary: "GatsbyJSで作成したブログに、検索フォームを実装してみました。Algoliaの様に全文検索とまではいきませんが…"
tags: ["GatsbyJS"]
---
例えばこの記事だと、gatsbyjs、ブログ、検索フォーム、全文検索 などの語句を使って、要約を作成するという感じですね。
そんなことを考えている時に、以下のブログに行き着きました。
参考にさせて頂いた記事
今回は、diff001a さんの方法で実装してみることに!
工夫した点
MDN Web Docs の記事は、filter や indexOf の使い方が、詳しく書かれています。
(自分の場合は)Index ページに検索フォームを設置しているので、投稿された記事一覧を取得するクエリをそのまま使って、(検索用に別途クエリを作成しなくても)実装が出来ました。
検索ワードが入力されたら、キーワードに一致する記事を絞り込み、検索フォームの下に表示する様にしてみました。
検索ワードが入力されていない場合は、投稿されている全記事が表示されます。
(検索ワードを入力した場合)タイトルだけではなく記事の要約も表示されるので、(クリックせずとも、なんとなくですが)あ〜、こんな内容の記事なのね…と理解出来るかなぁと。
最後に、検索フォームにフォーカスが当たった際のアニメーションですが、特に意味はありません。
そういえばフォームに CSS の transition を適用したことないなぁ…と思っていたので、今回ちょっと試してみたまでです。