Qiitaの記事検索サービス「Qiiguru」を半日で開発してみた

# 1. はじめに
Qiitaの記事検索サービス「[Qiiguru](https://qiiguru.netlify.app/)」を開発しました。
サイトURL：https://qiiguru.netlify.app/

![Qiiguru.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882682/33e44485-d00c-9cba-d652-7441a00983b2.gif)

## 1.1 開発背景

突然ですが、Qiitaを使っていて、このような悩みはありませんか。

```
検索オプション機能があるけど、使いづらい
```

Qiitaでは通常キーワード検索をしますが、以下を指定することで詳細に検索することが可能です。

| 項目 | オプション |
|:-:|:-:|
|　タイトルに「2015」を含んでいる　|　title:2015　|
|　本文に「Qiita」を含んでいる　|　body:Qiita　|
|　コードに「Ruby」を含んでいる　|　code:Ruby　|
|　...　|　...　|

参考：https://help.qiita.com/ja/articles/qiita-search-options

しかし、**わざわざ`title:2015`や`body:Qiita`で検索するのはめんどくさい**ですよね。

そこで、**これらのオプションも簡単に入力できるQiitaの記事検索サービスを開発しよう**と考えました。

## 1.2 類似サービス調査

すでに同じようなサービスがあると思い、少し調査したところ、Qiigleというサービスがありました。
参考 : [【Qiigle】というQiitaの記事を検索するサービスを作りました](https://qiita.com/d0ne1s/items/ea9d0154d56c7cfd2128)

こちらのサービスの特徴をまとめると以下になります。

```
1. ユーザ名、タイトル、本文、タグで検索可能
2. 検索後にQiita APIで検索結果を本サービス上に表示
3. 検索結果のリンクをクリックするとQiitaの該当記事にアクセス
```

上記サービスでも良いのですが、私として以下を実現したいと考えていました。

```
- ストック数で検索したい
    - 質の良い記事である可能性が高いため
- 作成日で検索したい
    - 直近1年とか、最近の記事を検索したいため
- 検索後は直接Qiitaの検索結果を表示したい
    - わざわざ検索結果を表示する画面を作成するのが手間&意味があまりないと考えたため
```

# 2. 開発内容詳細

## 2.1 仕様

- 以下項目を入力し、Qiitaの記事を検索できます。
    - キーワード
    - タイトル
    - 本文
    - ストック数
    - 作成日
- 作成日についてはデフォルトで1年前の日付を設定しています。
    - 基本、古い記事にアクセスしないようにするため
- 検索ボタン押下をトリガーに、**クエリパラメータ**を作成し、以下のURLを開きます。

```js
https://qiita.com/search?q=クエリパラメータ
```

- 複数入力があった場合は**AND条件**となります。

## 2.2 使用技術

### プログラミング言語
- HTML5
- JavaScript

### フレームワーク

- React
    - 自身の勉強のために、Reactで開発してみました。

### ライブラリ
- Material UI
    - 自身の勉強のために、Material UIを使ってみました。

### ホスティングサービス
- Netlify
    - 無料で簡単にデプロイできるので、利用しました。

### その他
- ESLint
    - ソースコードの品質向上のため、導入しました。
- アイコン作成ツール:[BrandMark](https://brandmark.io/)
    - ポチポチ条件を入力するといい感じのアイコンを作成してくれるので良いです。
- Google Analytics
    - アクセス数をチェックするために導入しました。

## 2.3 ソースコード(抜粋)

デザインはMaterial UIのみを使用しており、CSSは書いていません。
useStateで各項目の状態を管理しています。
検索ボタン押下後にopenQiitaという関数を呼び出します。

```js
  return (
    <Container maxWidth="sm" sx={{ pt: 5 }}>
      <Grid container justifyContent="center">
        <img src={logo} alt="Logo" style={{ width: '100%' }} />
        <p>QiitaでググるためのWebサービス</p>
      </Grid>
      <Stack spacing={3}>
        <TextField onChange={(event) => setKeyword(event.target.value)} label="キーワード" placeholder="プログラミング" />
        <p>詳細に検索したい場合は以下を指定してください。</p>
        <TextField onChange={(event) => setTitle(event.target.value)} label="タイトル" placeholder="Ruby" />
        <TextField onChange={(event) => setBody(event.target.value)} label="本文" placeholder="Ruby" />
        <TextField onChange={(event) => setStock(event.target.value)} type="number" label="ストック数" placeholder="100" />
        <TextField onChange={(event) => setCreatedDate(event.target.value)} type="date" defaultValue={initialDate} helperText="指定した日付以降に作成された記事を検索(デフォルト:1年前の日付)" />
        <Button onClick={() => openQiita()} color="primary" variant="contained" size="large">
          検索
        </Button>
      </Stack>
    </Container>
  );
```

openQiitaでは入力項目からクエリパラメータを生成して、Qiitaを別ページで開いています。

```js
  function openQiita() {
    const queryParamters = [];
    if (keyword) {
      queryParamters.push(keyword);
    }
    if (title) {
      const titleParameter = `title:${title}`;
      queryParamters.push(titleParameter);
    }
    if (body) {
      const bodyParameter = `body:${body}`;
      queryParamters.push(bodyParameter);
    }
    if (stock) {
      const stockParameter = `stocks:>=${stock}`;
      queryParamters.push(stockParameter);
    }
    if (createdDate) {
      const createdDateParameter = `created:>=${createdDate}`;
      queryParamters.push(createdDateParameter);
    }
    const qiitaUrl = 'https://qiita.com/search?q=';
    const qiitaSearchUrl = qiitaUrl + queryParamters.join('+');
    window.open(qiitaSearchUrl, '_blank', 'noreferrer');
  }
```

## 3 今後の予定
- 他の検索オプション(タグやソースコードでの検索など)にも対応する
- Qiita APIを用いて、検索結果を自前で作成した画面に表示してみる