見出し画像

ハッシュタグ機能の実装方法と方針

プログラミングで個人開発をしていてSNS関係である場合高確率でユーザーがハッシュタグを投稿につけれる様にしたい・ハッシュタグから投稿を検索できる様にしたい!と言った需要が出てくると思います。

ハッシュタグ機能自体は身近なものですが実装方法を知っていないと案外難しく検索をしようとしてもヒットしやすいハッシュタグ一覧だったりの情報が出てきてハッシュタグ機能自体の実装について書かれた記事は出てきません。(単純に自分の検索不足だとは思いますが)

そこで今回はハッシュタグ機能を作る時にサーバーサイドとフロントエンド側で考慮するべきことについてまとめておきます。また特定の言語で実装というよりかは考え方だけ載せておきます。

機能要件

まずハッシュタグ機能を作るにあたりどの様な機能を持っておくべきかの機能要件について書き出します。

  1. ユーザーが投稿を行う時にハッシュタグを入れれるようにする(ハイライトができるとベター)

  2. 投稿を行う際投稿から使われているハッシュタグを検知して投稿とハッシュタグ情報を紐付け

  3. 投稿表示の時にハッシュタグを表示(ハッシュタグは色を変更・ハッシュタグをクリックした時にそのハッシュタグが使われている投稿一覧を表示できるとベター)

大きく分けて3つだと思います。1, 3にどうするともっとよくなるかを書いていますが正直実装しないと最低限なものになってしまうのでベターというよりほぼニードでしょうか?

明らかに機能要件が雑すぎるのは分かっているのですが全部書き出していたらキリがないので、、、Twitterのハッシュタグ機能と同じような感じだと思ってください。

機能実装

ここからは先ほどあげた3つの機能をどのように実装すれば良いか・どのようなルート(クエリ・ミューテーション)が必要になってくるかを説明していきます。

ユーザーが投稿を行う時にハッシュタグを入れれるようにする

まず前提としてフロントエンド側でユーザーが入力できるテキストフィールドが必要になってきます。入力後なんだかのボタンを押すとそれがバックエンドに送信される仕組みが必要になってきます。それ自体はそこまで難しくないと思います。

ハッシュタグが入力された時にハイライトするような機能についてですが調べていても自前で実装するのは難しいと感じました。大人しくライブラリを使うのが良い気がします。候補としてはDraft.jsLexicalが挙げられます。

もしテキストフィールドとハッシュタグの入力ボックスを分けて良いのであればreact-tag-inputといったライブラリも候補に挙がってきます。

Draft.jsやLexicalを使った場合入力を独自のJSON形式として出力して表示できたりすることもできます。そのJSONをデータベースに保存しても良いですしテキストのみの保存でも良いです。ここはどのように表示したいかに大きく依存する気がします。ライブラリへの依存度を下げたかったりデザインを変更したいというのであればテキストを保存するだけで良い気がします。フレームワークから出されるJSONごとバックエンドに保存したり送信したりする場合既に情報を取得してくれたりすることがあるので以下の手順が変わってくると思います。

投稿を行う際投稿から使われているハッシュタグを検知して投稿とハッシュタグ情報を紐付け

実際にユーザーが投稿内容を入力して保存するときの処理です。データベース設計が思いのほか複雑になってきます。

ハッシュタグとユーザー・投稿の関係を言葉にしてまとめてみます。

  • ユーザーは複数の投稿を持っている

  • 投稿は1人のユーザーが持っている

  • 投稿は複数のハッシュタグを持っている

  • ハッシュタグは複数の投稿に持っている

以上の関係により以下のリレーションが成り立ってくると思います。

ユーザー・投稿→one to many
投稿・ハッシュタグ→many to many

(匿名投稿やハッシュタグの所有権を認めるといった機能が欲しい場合はリレーションが変わってきますが今回は考えません。)

テーブルとしては4つ必要になってきます。これもフレームワークや言語によって命名規則が変わってきます。ものによってカラムも変わってくるので明示しません。なんとなくイメージを持ってもらえたらと思います。

  • Users→ユーザーの情報を管理するテーブル

  • Posts→投稿を管理するテーブル

  • Tags→ハッシュタグを管理するテーブル

  • Posts_Tags→Posts, Tagsの中間テーブル


さてデータベーステーブルはできたと思うので今度はサーバーサイドのAPIの方を実装してきます。投稿の保存はもちろんなのですがその投稿からハッシュタグの検知を行う必要があります。APIとしては以下が必須です。

  • post/create → 投稿を保存するAPI

検知方法については正規表現を使っていきます。具体的には以下の正規表現です。

/#+([a-zA-Z0-9亜-熙ぁ-んァ-ヶー-龥朗-鶴.\-_]+)/g

これを投稿内容に対して検索するとハッシュタグ一覧が入ると思います。ハッシュタグは先頭の「#」を抜いた上で配列に入れるなりして保有して投稿内容を保存した上でデータベースに一つ一つ投稿と紐づけて保存してください。ハッシュタグが初めて使われた場合はTagsテーブルにも保存・既にある場合は関連付けのみ行うといった形のCreateOrInsertといった形で実装するのが良いと思います。ORMにそのような機能がない場合は存在を確認してないものは事前に保存する必要があります。

以上でタグと関連づけた状態で投稿を保存する機能が出来上がったと思います。

投稿表示の時にハッシュタグを表示

フロントエンドで例えば「posts/[id]」(idは変数)ルートにアクセスがあった場合に投稿を表示できるように実装しましょう。バックエンドのAPIを叩いて投稿を取得し内容を表示すれば最低限の機能は出来上がります。サーバーサイドで必要になるAPIは以下です。

  • posts → 特定の投稿の取得 無限スクロールやページネーションも欲しいのでクエリとしてcursorやtakeといった情報もとるようにすると良い アプリケーションによってはフォローしているユーザーのみから取得といった機能も必要

  • posts/[id] → 特定の投稿の詳細情報を取得するためのAPI

  • tags/[tag name] → タグの名前からそのタグが使用されている投稿一覧を取得。こちらもページネーションができるようにしておきたい

ページネーション周りのイメージは自分の記事ではありますが以下が参考になると思います。

投稿にハッシュタグが使われていた場合についてはこれもまた正規表現でテキストを検索して該当のものは色を変えるといった手法を取ると良いです。また色を変えるだけでなくaタグとして表示してハッシュタグ一覧表示ができるようなページに遷移させるとそれっぽい機能になります。

まとめ

以上がタグ機能の実装についてです。ほんのコア機能の説明だけでしたがイメージは掴めたと思います。コア機能について実装できたらそこから応用して関連機能の実装できると思います!


この記事が気に入ったらサポートをしてみませんか?