株式会社クイックのWebサービス開発blog

HAPPYなエンジニア&デザイナーのブログです

Amazon CloudSearchを簡易の検索用DBとして気軽に使う【事例・プログラミング不要】

プランナー兼ディレクターのyumeです。

複数のツール・システムを運用するケースって非常に多いと思うのですが、 だいたいの場合、しばらく経つと

「ツールAでシステムBの情報を検索した結果を取ってきてゴニョゴニョしたい!」

ってなりますよね。

そういうときに、すぐAやBの改修ができるエンジニアに依頼できる状態ならよいのですが、 他の案件にかかりきりで、地味な改修を誰にも依頼できない…ってこともよくありませんか?

そんなときに、Amazon CloudSearchという手段も検討してみてはいかがでしょうか。

こんな要件にオススメ

  • 検索対象のデータを出力したファイルを生成できる
    • XMLまたはJSONだと自動化も可能!
  • APIで条件検索した結果を取得できるようにしたい
  • ただしAPIの自前開発をする余力がない
  • (既にAWSを使っていて、新たにアカウント発行とかクレカ登録とかする必要がない)
  • (検索対象が膨大なサイズでない)

CloudSearchって?

Amazonが提供している、検索ソリューションを簡単に構築できるサービスです。
日本語のあいまい検索やサジェストの提示ができるので、弊社では以前からサイト内検索に利用しています。

Amazon CloudSearch (クラウド内の検索サービス)| AWS

え!?CloudSearchって文書検索じゃないの!?

CloudSearchと言えば、「日本語解析して単語ベースで検索」「自動入力候補の表示」などの目玉機能があり、なんとなく

「フリーテキストで検索するシーンで使うんだろうな〜」
「複雑な検索するのに向いてるサービスなんだろうな〜」

と思いがち※ですが、属性を利用した単純な検索でも充分利用する価値があります。
※筆者の主観です

例えば、以下のような元データがあったとしましょう。

ID テキスト 日付 投稿者 お店の緯度経度
1 ここのカオマンガイ屋は骨入スープが最高。 2018-10-10 A 35.655898,139.705498
2 とにかく餃子がうまい! 2018-07-10 B 35.666781,139.750832
3 2度食べてハマる麻婆豆腐。 2018-04-10 C 35.667239,139.752888
4 個人的にこの近辺で一番魚がうまい。 2018-01-10 C 35.669347,139.738818

(どの店も私のオススメなので、都内の方は緯度経度から検索してぜひ行ってみてください♡)

この場合、CloudSearchでは以下のことがすべて開発なしでできるので便利です。

  • 食べ物の名前で検索する(あいまい検索もOK)
  • テキストの一致度や日付で並び替えをする
  • 投稿者が完全一致した場合のみに絞り込み
  • 緯度経度の範囲を指定して絞り込み

上2つのイメージが強いですが、単純な絞り込み検索や、空間検索もできるので汎用性は高いです。

「自宅から半径◯キロ以内で!」に近いこともできそうですね。

Amazon CloudSearch での地理的位置による検索および結果のランク付け - Amazon CloudSearch

ざっくり手順

詳しくはAmazonのヘルプを参照してください〜ここでは流れのイメージだけ(๑•̀ㅂ•́)

1. Amazon CloudSearchで検索ドメインを作成する

  • AWSのコンソール上でポチポチ設定する
  • 必要に応じてアクセス制限を設定

Amazon CloudSearch ドメインの作成 - Amazon CloudSearch f:id:aimstogeek:20181010100125p:plain

2. 必要なフィールドと型を洗い出す

下記のようなフィールドが必要になるかと思います。

  • 検索条件になるフィールド
  • 検索結果に必要なフィールド

それぞれのデータが何型か(日付型なのかテキスト型なのか)を検討します。

3. 作成したドメイン上で、フィールドを設定する

  • コンソール上でポチポチ設定する
  • 型によってデータの表記法が決まっている(特に日付型)ので、データ作るより先にこちらを決めるのがオススメ

Amazon CloudSearch ドメインのインデックスフィールドの設定 - Amazon CloudSearch

4. 上記に合わせた検索用データを用意する

  • XMLJSONだと、コンソールからもAPI経由でもアップロードできて良い
  • 難しければCSVで作成し、コンソールから手動でアップする運用も可

Amazon CloudSearch 用にデータを準備 - Amazon CloudSearch

5. 検索用データをアップロードする

ここまで対応すると、API経由で対象データを検索できるようになります!

絞り込み検索のイメージ

コンソール上の「Run a Test Search」で、検索結果をプレビューすることができます。

全件検索するには、"Search:"に「*:*」を入れ、"Options"の"Query Parser"を「Lucene」に変更します。
Searchには通常、検索したいテキストを入力しますが、全件の場合(テキスト検索をしない場合)は「*:*」と指定するようです。 f:id:aimstogeek:20181010112431p:plain

Search欄についてですが、ここで指定したテキストは、単純に検索可能なフィールド全体が検索対象となります。

時に、完全に一致していないレコードもヒットして返ってきますし、検索対象となるフィールドを指定することもできません。

一方で、「このフィールドがこの値に完全一致したとき」という条件で検索したい場面もあると思います。

というか、「えっ…単純にRDBMS的に検索条件セットするので充分なんだけど…」ということのほうが多いと思います。
この場合は絞り込み検索です。

絞り込み検索を行うには、"Filter Query"に条件を指定していくことになります。

投稿者がCのレコードのみを検索するには、以下のようにします。 f:id:aimstogeek:20181010112600p:plain

「この検索結果をAPI経由で取得するにはどうすればいいんだ?」となった場合は、
同じページ内の「JSON」リンクをクリックすると以下の画面が表示できます。 f:id:aimstogeek:20181010113008p:plain 赤矢印の箇所が該当の検索リクエストになっているので、コピペして連携させたいシステム側からcurl等で叩いてあげればOKです。

料金

料金はインスタンスのサイズと起動時間でほぼ決まります。
詳細は以下のページが非常にわかりやすいです。(ちょっと古いですが)

Amazon CloudSearchの見積方法について | ナレコムAWSレシピ

安く済ませるには、使わないときはインスタンスを停止させればいいじゃん!と思いましたが、
どうやら削除か起動かしかないようです。

予めデータ量などが分かっている場合は、以下のツールで試算するといいと思います。

Amazon Web Services Simple Monthly Calculator

まとめ

以上のように、プログラミングをすることなく検索用DBを持てる点と、即座にAPIが利用できる点が、CloudSearchの便利なところです。
また、リクエストやアップデートに応じたスケーリングも勝手にやってくれるので、その点は楽です。

ですが、データの二重管理になってしまう、コスト試算がしづらい等、長年運用するケースに不向きな面もありますので、
状況に合わせて選択肢の1つになるかもなというくらいでのご紹介でした。

こういう状況でむしろこうしたほうがいい、このツールもオススメ、というものがあればぜひ教えてくださいm( )m


\\ 『明日のはたらくを創る』仲間を募集中!! // 919.jp

Laravel5.6とVue.jsでクリーンアーキテクチャを目指す

先日の台風により楽しみにしていたライブが中止になりブルーなぱふゅーむです。

最近新規サイトの構築でアーキテクチャについて、プロジェクトメンバーで議論する機会がありました。 そのプロジェクトは新しい試みとしてスクラム開発を行なってるのですが、今回はスクラム開発の話ではなく新規サイトのアーキテクチャについて話したいと思います!

スクラムについてはスクラムマスターのフルーツパーラーが記事を書いていますので興味がある方は是非!

スクラム開発はじめます - 株式会社クイックのWebサービス開発blog

技術要件

使用する技術セットについては以下になります。今回の話にはあまり関係がないところですので、詳細は割愛させていただきます。

全体構成

f:id:aimstogeek:20181004160749p:plain

アーキテクチャは大まかに分けてこのような構成になっています。

  • Controllerクラス・・・viewを返すControllerとデータのやりとりをするApiController
  • Serviceクラス・・・ユースケースを纏めたクラス
  • Repositoryクラス・・・DBとやりとりをするクラス
  • Modelクラス・・・Entity

Controllerクラス

Controllerは以下2種類のコントローラに分けています。

  • 単純にviewを返すController(ViewController)
  • 実際にデータの受け渡しを行うApiController

アプリケーションがRequestを受け取るとまずController(ViewController)はリクエストパラメータをviewに返します。この段階では特にデータの取得・削除などは行いません。単純にリクエストパラメータとともにviewを返すようなイメージです。

viewはいくつかのvueコンポーネントから構成されています。各vueコンポーネントはControllerから必要なパラメータを取得し、表示に必要な情報を取得するため再度非同期で各ApiControllerにRequestを送ります。

基本的にはcomponentとApiControllerは1対1の関係を考えています。ケースによっては多対1(複数コンポーネントから呼ばれるApiController)にはなりえるかもしれませんが、1対多はできる限り避けたいと考えています。理由としては1対多の関係になると、トランザクションをApiControllerではれなくなるためです。

下記はApiControllerの一例です。

<?php

namespace App\Http\Controllers\Api;

class UserController extends \App\Http\Controllers\ApiController
{
    /**
     *
     *
     * @param  int          $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function detail(int $id): \Illuminate\Http\JsonResponse
    {
        $service = new \App\Services\UserService();

        return $this->renderJson([
            'user' => $service->fetchUser($id),
        ]);
    }

Userを取得する処理は後述するServiceクラスに任せます。

Serviceクラス

Serviceクラスはユースケースをまとめたものです。例としてUserServiceクラスをあげます。Userに関わる振る舞い(ユースケース)としては以下のようなものが考えられます。

  • ユーザ情報を取得
  • ユーザ情報を登録
  • ユーザ情報を編集

上記のような振る舞いをまとめたものがUserServiceクラスになります。 Serviceクラスで重要なことはビジネスロジックのみを記述し、データ取得などModelとのやりとりはRepositoryクラスに任せることです。(取得したデータをApiControllerに渡すために加工が必要な場合はServiceクラスで行います。)

設計の段階でServiceクラスとRepositoryクラスを分けるかどうかメンバー間で議論をしたのですが、Serviceクラスでビジネスロジックとデータ取得等DBとのやりとりを一緒に書くと、冗長な記述が多くなり、Fatロジックになりがちとの結論により分離することになりました。

一例としてユーザ情報を編集する処理がUserServiceクラス以外で必要になったとしましょう。その場合Serviceクラスをビジネスロジックの記述のみに抑えることにより、実際にDBにアクセスしてユーザ情報を編集するという処理を共通化することができます。

Repository層にDBとのやりとりを任せることで、各Serviceクラスから使いまわすことができるようになります。

<?php

namespace App\Services;

class UserService
{
    /**
     *
     *
     * @param  int          $id
     * @return \App\Models\User|null
     */
    public function fetchUser(int $id): ?\App\Models\User
    {
        $repo = new \App\Repositories\UserRepository();

        return $repo->find($id);
    }

Repositoryクラス

LaravelのEloquentモデルはEntityとしての役割と、DBのデータ操作をする2つの責務を持っていますが、その責務を分離したかったためRepositoryクラスを実装することになりました。Repositoryクラスはデータの取得・編集・削除など DBとのやりとりを行うクラスになります。ModelクラスはあくまでEntityとしての振る舞いを持つクラスにとどめます。

<?php

namespace App\Repositories;

class UserRepository
{
    /**
     *
     *
     * @param  int          $id
     * @return \App\Models\User|null
     */
    public function find(int $id): ?\App\Models\User
    {
        return \App\Models\User::find($id);
    }

Modelクラス

Modelクラスは単純にEntityとしての振る舞いのみになっています。DBとのやりとりは前述したRepositoryクラスに任せます。Modelはテーブルと1対1の関係になります。

今後に向けて

プロジェクトメンバーでこういったアーキテクチャの話ができたのは非常に有意義で楽しかったです!これがベストなアーキテクチャかどうかはまだ分かりませんが、個人的にはスケールしやすい、いい設計ができたのではないかと思っています。現在ようやく設計フェーズが終了し実装に入ってきたところです。今後もプロジェクトメンバーで議論しながらよりよい柔軟なアーキテクチャを目指していきたいですね!では!ʅ(◔౪◔ ) ʃ


\\ 『明日のはたらくを創る』仲間を募集中!! // 919.jp

万物の真理『循環』について

最近セブ○レの「生ハムクリームチーズ バジルソース」にハマっている
hamanokamiです。

先週は毎朝食べてました。(今日はゆでたまご

「生ハム」「クリームチーズ」「バジル」を初めて合わせた人は天才やと思います。

ということで、早速ですが、
今回は万物の真理『循環』についてブログを書きます。

「循環とは」

  • 1 ひとめぐりして、もとへ戻ることを繰り返すこと。
    • 例)「市内循環バス」
  • 2 血液やリンパが体内をめぐること。

循環の大事さを理解できる実例

循環の大事さを知るのに非常に良い例が、
死海ガリラヤ湖」です。

死海は有名ですので、皆さんご存知かもしれないですが、
おさらいとすると、ヨルダン川等の7つの川が流入している湖で、
塩分濃度が海水の10倍の約30%のため、
何をしなくても人がプカプカ浮くことで有名ですよね。
また塩分濃度が高すぎるため、生物が生息できないことが観測されています。
※一部湧き水が湧き出ている場所だけは、生物が確認されているとのこと

変わって、ガリラヤ湖は知らない人が多いと思いますが、
死海と同じヨルダン川流入しているイスラエル最大の湖で、
新約聖書ガリラヤ湖とその周辺の地域を舞台とされているそうです。
死海と違い、塩分濃度は高くないため、
生物が生息しています。

f:id:aimstogeek:20180928180100p:plain
なぜ同じヨルダン川流入している湖にもかかわらず、
一方の湖では生物が生息していて、
もう一方の湖では生物が生息できないのでしょうか。

答えは、死海にはそこから流れ出る川がなく、
ガリラヤ湖にはあるということです。

f:id:aimstogeek:20180928180103p:plain
水が出ていく川がないことで、湖の水分は高温により蒸発し、
塩分はどこにも出ていく先がないため、
塩分濃度が高くなるという原理です。

少し強引ではありますが、
流れが止まる地点、つまり循環が終わる最終地点は、
「死」と解釈できます。

循環があることで、「生がある」と言えます。

人間もそうです。
心臓が動いていることで身体中に血液や酸素を巡るため生きていけますが、
心臓が止まると、血液や酸素は身体に巡らないため死に至ります。


つまり
「循環は生」
なのです。

日常に応用してみる

学習の効果を上げるには、
アウトプットするのが良いとよく言われます。

もしアウトプットがあったら・なかったらを図にしてみると、
こんな感じです。

f:id:aimstogeek:20180928180106p:plain
アウトプットをしなければ、
インプットした知識は活きず
忘れてしまいます。

アウトプットをすれば、
自分の血肉にもなりますし、
何かを教えるというアウトプットをした場合は、
他人へのインプットとなります。

その他人がまたアウトプットすることで、、、
という感じで循環が生まれると、
そのときのインプットは生き続けていると言えます。(多少強引ですが、、、

最後に

『循環』は万物の真理なのです。

というわけで、皆さん『循環』を意識して、Happyな生活をʅ(◔౪◔ ) ʃ


\\ 『明日のはたらくを創る』仲間を募集中!! // 919.jp

【SQL】ExcelでできるだけスマートにINSERT文を作成する方法を模索した

こんにちは。sanamekoです!

突然ですが、INSERT文を書くのってすごく大変ですよね!(個人の感想です。)
カラム名1,カラム名2,・・・カラム名N」の後に「値1,値2,・・・値N」と書くのが苦手で、最終的にカラムがずれてたり、カラム数足りなかったりってこと、よくあります!

手でガリガリ書かずに、うまいことツールを使ってラクに書けないものか・・・ヽ(ˇд ˇ;)ノ
ということで、「ExcelでできるだけスマートにINSERT文を作成する方法」を考えたいと思います!

「スマート」とは

ExcelでINSERT文を作成するという話はよく聞くので、今更感は否めませんが、今回は「スマート」をテーマに、下記のことを念頭において作ってみます!

  • 誰が見ても分かりやすい
    • マクロやVBAは使わない
    • あちこちに数式(関数)を散りばめたりせず、最小限のセルに抑える
    • 数式の中身を見なくても、何をやっているか大体分かる状態にする
  • メンテナンスや使い回しが容易である
    • カラムの増減にも簡単に対応できる
    • コピーして他のテーブルにも転用できる


他のひとが作ったExcelを解読したり修正するのって大変ですからね。できるだけシンプルに、スマートに作りたいです!
では早速いってみましょう!

叩き台

まず叩き台を作りました。 A1セルにテーブル名、A2~E2セルにカラム名、3行目以降はA列~E列に値を入力すれば、F列にINSERT文が完成します。

f:id:aimstogeek:20180918171706j:plain

作成されたINSERT文:
INSERT INTO t_sanameko (column1,column2,column3,column4,column5) VALUES (1,500,500,500,1500);

ポイント

  • 数式が入っているのはF列のみ
    • 修正時はF列の数式だけ直せばよい
    • レコード数が増えたら、F列の数式を下セルにコピーしていくだけでOK!
  • テーブル名・カラム名は数式内に直接書かず、シート上に書かれた文言を参照するだけにする
    • どのテーブル/どのカラムに値を入れているのか、数式の中身を見にいかなくても分かる
    • 他のテーブルに転用しやすい


肝心の数式の中身ですが、まずは&を使って文字列連結してみました。

f:id:aimstogeek:20180920140119j:plain

F3="INSERT INTO "&$A$1&" ("&$A$2&","&$B$2&","&$C$2&","&$D$2&","&$E$2&") VALUES ("&$A3&","&$B3&","&$C3&","&$D3&","&$E3&");"

うーん、いちいち&とか","をつけるの面倒ですね。カラム数が多ければ多いほど大変。
カラム増減に伴うメンテも面倒くさそう。ミスが起きそうですね・・・!

改良版その1(CONCATENATE関数/Excel

Excelには、CONCATENATEという、文字列を連結する関数があるそうな。

2 つ以上の文字列を 1 つの文字列に結合するには、文字列関数の CONCATENATE を使います。
書式: CONCATENATE(文字列 1 [文字列 2], ...)

先ほどの「叩き台」のF列の数式をCONCATENATE関数に置き換えてみます。

F3="INSERT INTO "&$A$1&" (" &CONCATENATE($A$2,",",$B$2,",",$C$2,",",$D$2&",",$E$2)&") VALUES (" &CONCATENATE($A3,",",$B3,",",$C3,",",$D3,",",$E3)&");"

ううーん、&がカンマ(,)に変わっただけですね・・・。手間は叩き台と何も変わらないです。

改良版その2(CONCATENATE関数/スプシ)

そういえば、前に雑談用チャットルームで何度か呟かれていたような・・・。
弊社には、業務中の感動を共有してくれるエンジニアがたくさんいます!ありがたいですね!

f:id:aimstogeek:20180920140644j:plain

f:id:aimstogeek:20180918171851j:plain
なお、同じことを何度も呟いてしまうことも。

ス、スプレッドシート!!!( ゚д゚)!!!

ちなみにExcelでは、Excel2016から追加された「CONCAT」関数を使えば、範囲指定した文字列連結ができるようです。(※Office 365ユーザーのみ)
弊社はExcelのバージョンが古いので、ここからはExcelではなくGoogleスプレッドシート(スプシ*1)を使うことにします。


早速、スプシ上で「改良版その1」を再現し、CONCATENATEの引数をセル指定から範囲指定に変更してみました。

f:id:aimstogeek:20180920140058j:plain

J3="INSERT INTO "&$A$1&" ("&CONCATENATE($A$2:$I$2)&") VALUES ("&CONCATENATE($A3:$I3)&");"

数式はだいぶすっきりしましたね!
ただこの方法は、画像の通り、カラムとカラムの間にカンマ(,)を入れる列が必要になります。うううーん、ちと面倒くさい・・・

改良版その3(JOIN関数/スプシ)

そういえば、MySQLにはCONCAT_WSという便利な関数があります。
文字列を連結するだけでなく、区切り文字まで入れてくれるという優れものです。

連結されたものをセパレータ付きで返します
CONCAT_WS( 区切文字列, 文字列1, 文字列2, ・・・文字列N )

スプシに同じような関数ないかな?とググってみると、「JOIN」という便利な関数を発見しました! 早速使ってみます。

f:id:aimstogeek:20180920140257j:plain

F3="INSERT INTO "&$A$1&" ("&JOIN(",",$A$2:$E$2)&") VALUES ("&JOIN(",",$A3:$E3)&");"

シートの見た目も数式も、とてもスッキリしました! 範囲指定だからカラム増減にも強いですね!
Excelでも「TEXTJOIN」という関数で同じようなことができますが、こちらもExcel2016でのみ使用できるようです。


さて、ここで「数値型カラム限定かよ!」という声が聞こえてきそうですね!
そうなんです、文字型カラムはシングルコーテーション(')で囲んであげたり、日付型カラムは書式を整えてあげる必要があります。

「改良版その3」をベースにし、カラムの型も考慮して完成版を作ってみました!

完成版

「各カラムの型(2行目)」「作業用セル(F列~J列)」「型の変換パターン(M列~N列)」を追加しました。

f:id:aimstogeek:20180920141304j:plain

f:id:aimstogeek:20180918184437j:plain
※変換パターンはDBの種類によって異なります。

何をやっているか簡単に説明します。
1.まず作業用セルで、各カラムの型に応じて書式を整えます。

F4=SUBSTITUTE(VLOOKUP(A$2,$M:$N,2,false),"@@@",A4)

2.このF4セルの数式を作業用セルすべて(F列~J列)にコピーします。

3.K列に、先程と同様にJOIN関数でINSERT文を作成していきます。(ここで参照するのは作業用セル)

K4="INSERT INTO "&$A$1&" ("&JOIN(",",$A$3:$E$3)&") VALUES ("&JOIN(",",$F4:$J4)&");"

これでおしまいです٩( ‘ω’ )و

作成されたINSERT文:
INSERT INTO t_sanameko (id,name,price,like,created_at) VALUES (1,'えりんぎ',138,'好き',cast('2018/04/01' as date));

反省点

もっとスマートにできそうですが、sanamekoにはこれが限界でした。
以下、反省点です。

  • 作業用セルは作らず、数式は1セルだけにしたかった。
    • カラムの増減で、作業用の列も増減しなきゃいけないのは手間
  • NULLのとき考えてなかった・・・。作業用セルに分岐入れるか・・・。
  • 数式が入っているセルは背景色をつけたり太枠で囲えばより分かりやすいかも。
  • 記事タイトルに「Excel」と書いたのに結局スプレッドシートになってしまった。

もっと精進します。ではでは~~!

[追記]スプシがさらにスマートに!

弊社エンジニアのねこちゃんが、このスプシに改良を加えてくれました!
これでもかというくらいスプシがスッキリしますので、ぜひぜひ試してみてください! aimstogeek.hatenablog.com


\\『明日のはたらくを創る』仲間を募集中!! // 919.jp

*1:世間ではスプレッドシートのこと「スプシ」って略すみたいですね!私も流行りに乗っかって使ってみます。

【GoogleDrive】チームドライブの運用で涙を流した「漢」の嘆き

こなさんみんばんは!!
Windowsが大嫌い!Linux大好き!!ヘルプデスク担当のてるりんです。

GoogleDrive皆さん使っていますか?
メチャクチャ便利ですよね!

弊社のとあるプロジェクトで作ったチームドライブの運用者の方から運用で困っているとお悩み相談を頂き、 解決策がないかなーと模索し涙を流したお話。

相談内容

①検索結果からファイルのパスが拾いづらい!何とかならない?
GoogleDriveの検索は指定した条件で検索すると
サクッと検索結果が出てくるので超便利!と思っていたのですが、
検索結果で表示されたファイルがどこのパスにあるかパッとわかりづらいんですよね。

②大量にフォルダがあると、どのフォルダにいつファイルがアップロードされたかがわからないから何とかならない?
フォルダが少数なら原始的にポチポチフォルダを漁ることできるけど、大量にフォルダがあると判別不能
GASでゴニョゴニョしてスプレッドシートに情報出力とかで解決できるのだが、数が大量にあると話は別。

フォルダが大量にある背景として、ファイルアップロード者が多数おり、フォルダ作成の手間を省く為、
予め空のフォルダを大量に作成している。

頂いたオーダー

  • 万単位であるフォルダの中から、ファイルがアップロードされているフォルダの情報抽出。
  • 抽出したフォルダにファイルがいつアップロードされたかの日付情報が欲しい。
  • 但し、空のフォルダも超大量にあるのでそれは除外して欲しい。

問題解決するにあたって念頭に置いていた事

  1. 長ったらしいコードはガリガリ書かない → 自分の手を離れた時に後任が悲鳴を上げる。メンテもだるい。
  2. 既成品のツールとちょっとしたコマンドだけで何とかしたい → 誰が見てもすぐわかる様な状態にしたい。
  3. 全自動化したい → やっぱ楽したいねん(´・ω・`)

対応策その1

やっぱりGoogleと言えばGASでしょ!

  1. GASで全フォルダのリスト取得
  2. リストを基に全フォルダのファイル格納状況を確認
  3. ファイルがヒットしたら最新のファイルの日付けを取得
  4. スプレッドシートに出力

ザックリ上記の流れでGAS書いてみましたが・・・
APIへのリクエスト上限、メモリ上限の壁にぶつかり処理件数を分割したりして
ゴニョゴニョしましたが状況変わらずで結果は惨敗orz
てるりん涙を流す(´;ω;`)

対応策その2

LinuxでGDrive使ってみた!

LinuxでのGoogleDriveクライアントのひとつ。

$ gdrive list

上記はWindowsでいうDIRコマンド、Linuxでいうlsコマンド。
欲しい情報はこれで拾える!そして速度がめっちゃ速い!!
コマンド軽くパイプで繋げてやりたい事を叶えてくれる気がする!

君に決めた!!

と思ったらチームドライブ非対応ヽ( ・∀・)ノ┌┛)`Д゚)・;';
お蔵入り。
てるりん涙を流す(´;ω;`)

参考:https://github.com/prasmussen/gdrive
細かいセットアップ方法、使い方は( ՞ਊ ՞)☝を見てね。

対応策その3

Linuxでrclone使ってみた!

LinuxでのGoogleDriveクライアントのひとつ。
GoogleDriveだけじゃなくAWSのS3、DropBox、OneDriveだったり
多数のクラウドストレージに対応しているのが売り。
そしてチームドライブにも対応している!

$ rclone lsl [DriveName]:[FloderName]

対応策その2同様、上記はWindowsでいうDIRコマンド、Linuxでいうlsコマンド。

欲しい情報はこれで拾える!そして速度がめっちゃ遅い!!\(^o^)/
8時間待ってAPIへのリクエスト上限になりお蔵入り。
てるりん涙を流す(´;ω;`)

参考:https://rclone.org/
細かいセットアップ方法、使い方は( ՞ਊ ՞)☝を見てね。

対応策その4

Linuxgoogle-drive-ocamlfuse使ってみた!

LinuxでのGoogleDriveクライアントのひとつ。
このツールはLinux上にGoogleDriveのマウントができて超便利なんですよね。
マウントしてからはCUIでいつも通りのコマンドでGoogleDriveを触れるのがとても好感持てました。
もちろんチームドライブにも対応( ・`ω・´)

$ find /mnt/google_drive -name *.jpg -o -name *.heic -type f -exec ls -l {}\; > hoge.txt
 ※-execよりxargs ls -l ←のが速い・・・。

遅い!遅すぎる!!というか固まる(;゚Д゚)
なのでお蔵入り。
てるりん涙を流す(´;ω;`)

対応策その5

初心に返ってWindowsでDriveFileStream使ってみた!
GoogleDrive使ってる方でしたらWindowsMac問わず、 もう説明不要のアプリですよね!!
Windowsから直接GoogleDriveを触れるので対応策その4同様、
Linuxのfindっぽく検索できないかと思い(Macでええやんという突っ込み禁止)

Get-ChildItem -Recurse G:\チームドライブ\ぷろじぇくと | ?{ $_.Length -ne $null } | Select-Object Fullname,LastWriteTime | Export-CSV C:\temp\directory_check.csv -Encoding Unicode

PowerShellで↑試してみたところ10万件前後のフォルダ一通り舐めるのに15分程度で速い!!
後は出力したCSVをエクセルのVBAで成形&取り込みし、欲しい情報の一覧ができました!!
結果はオーライですが、エクセルで取り込んだり一手間あるし、全自動化が厳しいのでお蔵入り。
てるりん涙を流す(´;ω;`)

最終的な着地

以上の対応策を色々試した結果、

根本的にフォルダ構成の見直し、アップロードの運用方法を見直して空のフォルダ全部消して、アップロード時にフォルダ作成する様にお願いすれば解決するんじゃない?

というシンプルな結論に至りました。

これらを踏まえて思ったこと

  • 試した手法全部不要になりましたが、GDrive、rclone、google-drive-ocamlfuseこれらのツールはLinux運用する上でケースによっては色々使えそう。 是非Linux使いの方には触って頂きたいです。(ネット上だとUbuntu/Debian系での情報が多いですが、CentOS6/7系でも普通に使えました!)
  • 今の運用方法が正しいか常に疑うべし。 サーバ、PC運用する上で常に考えなければいけない事ですが、現状の運用方法、今ある形にとらわれすぎると良くない。 時には今ある運用の形を全部捨てるのも必要。
  • フォルダ構成、整理ってやっぱり大事。
  • DriveFileStreamはやっぱり便利! まだ使ってない方、使うと幸せになれますよ!
  • 対応策その5のワンライナーWindows系のファイルサーバ運用には使えるので是非お試しあれ!

中身の無いブログでしたが以上です!
あでゅー(´・ω・`)


\\『明日のはたらくを創る』仲間を募集中!! // 919.jp

チームビルディング:「マネージャーに求めるもの」編

みなさん、こんにちは。

フルスタックサラリーマン」こと、WEB事業企画開発室シニアマネージャーのnakayanです。
今週末、3ヶ月ぶりに髪を切ります。今年の夏は暑かった・・・

さて、前回はエンジニア採用について概要編として書いたのですが、特に各論で書くことがなかったことに気がつきました。これはヒドイ。
チーム拡大期の今、改めてチームビルディングについて最近考えていることが多いので、その一部を書いてみようと思います。

チームビルディングというと色々な要素がありますが、急拡大していくチームの中で特に問題となってくるマネジメントについて、というかマネージャーに求めるものについてまとめます。
自身の重要課題の一つに掲げているのが、「マネージャーの育成」です。

※ここでいう「マネージャー」とは、プロジェクトマネージャーではなく、組織マネジメントを担うマネージャーです。

色々な記事を読んでいく中で勉強になることが多かったので、参考・引用させていただきながら書きたいと思います。

組織における「リーダー」と「マネージャー」の違い

「リーダーシップ」や「マネジメント力」という言葉をよく耳にしますが、そもそも「リーダー」と「マネージャー」の違いって何なのかと疑問に思うところからスタートしました。

海外企業のトップは、「リーダー」と呼ばれている印象がありますが、何となく日本だと「メンバー」→「リーダー(主任・係長)」→「マネージャー(課長)」みたいな役職のイメージがあります。

が、ここで述べるのは役職の上下の意味ではなく、持っている資質としての違いです。どちらが良い悪いではないです。

  • リーダー:自ら先頭に立って進むべき道を示す存在

  • マネージャー:メンバーの一人ひとりが最高のパフォーマンスを発揮できるように支援する存在

おぉ!何となくイメージ湧きますね! だから海外企業のトップは「リーダー」と呼ばれるんですね。

リーダーとは

  • 組織全体がどちらに進むべきなのかを示す。
  • 明確なビジョンを示し、あるべき未来に向かって突き進んでいく原動力を生み出すという圧倒的なリーダーシップがいる。
  • 個性や価値観に関係なく「明確な方向性を提示する」「変革・改革を生み出す」「組織を一体化させる」という要素が必要。
  • 何よりも、リーダーには人を引きつける力が必須。
  • 上司として部下に偉そうな態度をとったり、命令口調で指示を与えたりするのがリーダーではない。
  • リーダーにふさわしい仕事ぶりを積み重ね、「この人についていきたい」と周囲に思わせたときに、初めてリーダーとなる。
  • リーダーシップを養い、リーダーを育成するには、重要な意思決定(責任)の場数が必要。

マネージャーとは

組織に属する一人ひとりの能力を見極め、パフォーマンスを最大限発揮できるよう、役割分担や成長を支援する。

ドラッカーが定義した「マネージャー」に求められる5つの役割

  1. 目標を設定する
  2. 組織化する
  3. モチベーションを高め、維持する
  4. パフォーマンスを評価する
  5. 自分も含めて部下を育成する

※ただ業務を振り分けるだけの人材はマネージャーとは呼べない。

組織全体を見渡し、それぞれの役割に適した人材を的確に配置する。そして、自分も含めて組織全体で成長を促していける存在となって、初めてマネージャーといえる。

下記の参考・引用元にもっと詳細に色々書いてあるので面白いですよ!

参考・引用元: u-note.me

冒頭で記載した「マネージャーの育成」という点に戻ると、会社における「マネージャー」というポジションは、おそらく「リーダー」「マネージャー」どちらの要素も求められていることがほとんどではないしょうか。
どちらに強みを持ったマネージャーになるかというのは、各自が意識してみると良いと思います。

ちなみにnakayanは、この違いを正確に認識する以前からこんなことを口にしていました。

「メンバーや仕事を管理したいわけじゃない。ビジョナリーであり、リーダーとしてチームをつくりたい。」と。

偉そうですねー。カーッ(゚Д゚)≡゚д゚)、ペッ

なので、まだまだ力不足ではありながら、どちらかを選べと言われたら「リーダー」でありたい!という想いです。
ちなみに、あまり管理能力が高くないので「せめて・・・」という気持ちでもあります(TдT)

「マネージャー」の役割とは

先ほど、"ドラッカーが定義した「マネージャー」に求められる5つの役割"がありましたが、ここでは「マネージャー」のポジションとして担う役割を記載します。(重複する内容もあります)

  1. チームの成果の最大化
  2. チームの成果の最大化を「生産性の高いやり方」で実行する
  3. 自身と部下の「価値ある人材への成長」
  4. 経営理念・ビジョン・目標・ルールの浸透

磨いていくべき仕事力

  1. 迅速な意思決定
  2. 成果につながる権限委譲
  3. ムダのない業務推進
  4. スピード感を生む時間活用
  5. 高生産性人材の育成
  6. 最強チームの構築

ひえぇ~!書いておきながら自分が全然できてないという・・・

参考・引用元:管理職1年目の教科書  櫻田 毅 (著)

「最強チーム」ってなんだよ!って思ったアナタ。
海軍の最強チームの本とか出ているので、そういったものを参考にしつつ、自分たちの会社・組織においての「"最強チーム"ってどんなチームだろうね」って議論を、マネージャー陣や場合によってはメンバーも含めて実施してみるのも面白いのではないでしょうか。

組織の成果を出すために

  1. 会社の業務の円滑な流れを維持するために、微調整やトラブル対応を行う。
  2. そのためには、公式の情報・人間関係だけでなく、非公式の情報(口コミ、噂話、人々の表情など)にも支えられた暗黙知と社内外の豊富な人脈を駆使する能力が求められる。
  3. そのような能力を武器にして、組織内の上と下、社内他部署と社外の人々からありとあらゆる情報と要望を受け取り、それを分析し理解したうえで、再び関係者に情報を伝達する。

組織の中のハブ(要)として機能するのがマネージャー。ハブが機能しなければ、組織全体が機能不全に陥る。
ハブとして効果的に機能するためには、社内、社外の関係者との間に生産的な関係性を構築する必要がある。

部下に対して

  1. 部下のエネルギーを引き出す
  2. 部下の成長を後押しする
  3. チームを構築・維持・成長させる

上司・トップに対して

  1. 結果で示す
  2. 説得力を持つ(相手を尊重しながら、自信を持って自分の言いたいことを相手に伝える)

社外に対して

  1. 最高のサービスを提供すること
  2. 企業の社会的責任を果たすこと

いやー、こういうのを目の当たりにすると超人ですね。でもやるしかない!!
できるようになったら相当楽しいと思います!!

参考・引用元: lightworks-blog.com

おまけ

少し前に、「新しい時代の「リーダー」に求められる10の要件とは?」という記事がありました。
これは「マネージャー」とはまた違って、これからの時代の経営者に求められるものという内容です。

新時代リーダーの10要件

  1. 課題設定力、先見性、仮説構築力、大局観
  2. 変化抽出力、変化適応力、カオス耐性、胆力
  3. 素直さ、伸びしろ、学習能力
  4. 自己効力感
  5. 比較優位となる強み(タグ)の認識と、機会開発力
  6. 多様性受容力
  7. 越境力、領域をつなぐ力、違う領域の人脈
  8. 共感力、熱量、物語力、チャーミングさ
  9. 機会提供力、コーチング力、環境整備力
  10. 意思決定力、実行力、仮説検証スピード

見るからに難しそうですね。

ちなみに自分はどうかなーと思って、各項目に対して自己評価してみました。
◎:優 ◯:良 △:可 ✕:不可

nakayanの自己評価

◯ 1. 課題設定力、先見性、仮説構築力、大局観
◎ 2. 変化抽出力、変化適応力、カオス耐性、胆力
◯ 3. 素直さ、伸びしろ、学習能力
△ 4. 自己効力感
✕ 5. 比較優位となる強み(タグ)の認識と、機会開発力
◯ 6. 多様性受容力
△ 7. 越境力、領域をつなぐ力、違う領域の人脈
◯ 8. 共感力、熱量、物語力、チャーミングさ
✕ 9. 機会提供力、コーチング力、環境整備力
◯ 10. 意思決定力、実行力、仮説検証スピード

ちょっと自己評価が甘い気がしますね・・・。

と、これを自分で考えているときに、食にうるさいマネージャーのZAWAが「ひとこと物申す!」と来たので、評価してもらいました。

aimstogeek.hatenablog.com

ZAWAから見たnakayanの評価

◯ 1. 課題設定力、先見性、仮説構築力、大局観
◎ 2. 変化抽出力、変化適応力、カオス耐性、胆力
◯ 3. 素直さ、伸びしろ、学習能力
◎ 4. 自己効力感
◯ 5. 比較優位となる強み(タグ)の認識と、機会開発力
◎ 6. 多様性受容力
◎ 7. 越境力、領域をつなぐ力、違う領域の人脈
◎ 8. 共感力、熱量、物語力、チャーミングさ
△ 9. 機会提供力、コーチング力、環境整備力
◎ 10. 意思決定力、実行力、仮説検証スピード

これは予想外!!食にはうるさいけど、上司への評価は寛大だった!!!!笑
うーん、自信は持ちつつ、自惚れずに精進していきます!

みなさんも、ご自身で評価してみるとどうですか?

参考・引用元: next.rikunabi.com

さいごに

「マネージャー」って難しいですよね。
現時点の自分がしっかりできているわけではないですし、、、

「マネージャーを育成する」となると、作業のように手取り足取り教えられるものでもないので、考え方や意識するポイントを共有しながら、自ら考え実践していく機会、重要な決断の機会などをどれだけ提供していけるかが重要ですね。
積極的に権限を委譲して、今以上に全員が自走し、加速成長していくチームをみんなと一緒につくっていきたいと思います。

それではまた(_´Д`)ノ~~


\\『明日のはたらくを創る』仲間を募集中!! // 919.jp

ページの表示速度を改善し、CVRを上げた話

こんにちは。夏バテ継続中のsatopiです。

Webサイト制作に関わる方は「表示速度が○秒遅いと離脱率が▲%上がる」という記事をよく目にすると思います。

今回は「それって本当?そんなに変わらないでしょう?」と疑いを持っている方に捧げます……ッ!

LPといえば、ABテスト

ある日、元となるスマホユーザー向けのLPからBパターンを作成し、時間をおいてから結果を確認したところ、BパターンのCVRが著しく低下していました。

A(元となるLP) B
CVR 0.59% 0.12%

なんと0.47ポイントも下がっています。

これは、一体……!?!? =͟͟͞͞( ´q` 三´q` =͟͟͞͞) エェェェ……

原因は表示速度

AとBの大きな違いは、元となるAでは画像メインでしたが、Bパターンで一部CSSコーディングし直し+αという点です。

思い当たる原因を調べてもそれらには問題なし。
様々な調査の最後にWebpageTestでページの表示速度を計測をしました。

A(元となるLP) B
Speed Index 1770 2085
Document Complete Time 3.528s 6.154s

LTE(12Mbps / 12Mbps 70ms RTT)を選択して計測しています。

  • Speed Index: ファーストビューがいかに早く表示されるかを表す新しい指標
  • Document Complete Time: HTMLコードにあるコンテンツをすべて読み込んだ時間

遅ッ…遅すぎる……。フロントエンドエンジニアとして、この計測結果は顔面蒼白ものです。Document Complete Timeが異常に遅い。

スマホユーザー向けのLPなので実機検証していましたが、Wi-Fi接続していて遅さを体感できておらず、気づくのが遅れてしまいました。

この遅さのせいでBパターンの離脱率が上がり、コンバージョンへ至らなかったに違いありません。

表示速度を改善

読み込みを遅くしていた要因を取り除き、改めて表示速度を計測。

A(元となるLP) B
Speed Index 1770 2023
Document Complete Time 3.528s 3.303s

元のLPよりも若干早くなり、いい感じですね。

では改めて、ABテストといきましょう!

       :
       :
       :

A(元となるLP) B
CVR 0.60% 0.85%

無事に、もともと比較したかった施策内容でのテスト結果を出すことができました!
(:3[___Ξ___]ε:)イェイイェイ!!ウォ!イェイイェイ!!!ウォウウォ!(:3[___Ξ___]ε:)イェ!!

表示速度が遅くなると離脱率が上がるのは事実」である。

二度と同じ失敗を繰り返さないぞ!!!!!と心に誓った2018年夏でした。


\\『明日のはたらくを創る』仲間を募集中です!! // 919.jp