データベース」カテゴリーアーカイブ

MEANでデグー飼育アプリを作ってみた

概要

  • 前々からMEANスタックに興味があった
  • 2017/01/22ぐらいからチマチマMEANアプリ作り始めた
  • とりあえず自分にとって実用的であるのが望ましいので、デグー飼育支援アプリを作った
  • MEANだとこんなことができるよの紹介を含め、動作画面を掲載する
  • 完全に個人用なのでサービスの公開はしないが、ソースコードはGithubで公開している

システム構成

OS + MEAN構成は以下の通り

構成要素 バージョン
Debian 8.7
Mongodb 3.2.9
Express 4.14.0
AngularJS 1.4.1
NodeJS 7.4.0

その他、主に開発に用いたツールなどは以下の通り

構成要素 バージョン
npm 4.1.2
babel 6.22.2
eslint 3.0.1
less 3.3.0
gulp 3.9.1
jQuery 3.1.1
jQUeryUI 1.8.19
bootstrap 3.3.7
d3.js 3.5.16
c3.js 0.4.1

ソースコード

https://github.com/Sa2Knight/degu-log よりクローン可能。

環境構築手順も一応READMEにあるので、頑張ればローカルでも動作させられる(多分)
Zaimアカウント及びZaimAPIを利用するためのトークンが必要だったり敷居は高い。

機能一覧

高速な画面遷移

初っ端から機能というより特徴の話だが、本アプリはSPA(っぽい何か)でありながら、URLを変更しながら画面遷移を行える。
そのため、ブラウザの「戻る」「進む」も利用可能であり、URLを直接指定して特定のリソースにアクセスすることもできる。

AngularJSのオプションモジュールである、ng-routeを用いることで、それを簡単に実装できた。
しかも画面遷移が非常に早い。これだけでMEANで開発してよかったと思えるレベル。

簡易ブログ機能

飼育に関する簡易的なブログっぽいものを投稿することができる。
ブログは通常のCRUDの他、カレンダーを表示して記事を一覧することができる。

体重管理機能

デグーの体重を時系列で管理することができる。便宜上、我が家のデグー2匹(パズー、メイ)に特化しており、それぞれ日付に対する体重を記録することができる。
また、時系列に記録した体重を元に、折れ線グラフをリアルタイムで描画することができる。

ペット関連支出管理機能

本機能は、クラウド家計簿サービスであるZaim及び入力した家計簿記録を取得するZaimAPIを用いて実装している。
日頃から入力している家計簿データを元に、月ごとの支出額の一覧及び特定月の支払内容を閲覧できる。

外部APIの利用もやはりSPAとの相性が抜群だ

写真管理機能

写真をアップロードして管理することができる。写真には、タイトル及び1つ以上のタグを付与することができ、それらで検索することができる。
また、写真アップロード時にオリジナルと別にサムネイルを生成し、写真一覧画面にはサムネイルが表示され、クリックすることでオリジナルサイズを確認できるようにアンっている。

所感

MEANという、MもEもAもNもほぼ使ったこと無い状態から、1つずつ勉強しながらなんとか実用性も多少あるWebアプリを作ることができた。特にSPAを1から作るのは初めての経験だったので、従来型のWebアプリとの違いを感じながら楽しく開発することができた。以下、主な所感を列挙する

  • MongoDBはJavaScriptライクに読み書きを行え、スキーマに依存せずにデータを管理できるので手軽で楽しい
  • AngularJSは双方向データバインディングが一番強いと思ったが、フルスタックのMVCであればAngularJSでなくても良いかなとは思う。
  • Nodeを使えばだいたいのことは対応するNodeモジュールがあって、サーバサイドを一通りJavaScriptで書ける。強い。
  • Expressについては、今回はRestfulなAPIサーバとしてしか使わなかったので触り程度しかわからなかった
  • SPAはクライアントの待機時間が極端に短くなるのでストレス無く利用できることを強く実感
  • クライアントサイドの負担を増やし、サーバサイドの負担を減らす新しい分散システムだと感じた
  • SPAでも画面遷移ごとにURLを変化させたほうが絶対便利だと思った
  • サーバサイドはRestfulなAPIに特化させるように実装したほうが分担が明確で良い
  • JavaScriptはBabelを導入して、全てES6で記述した。やはり最新仕様のJavaScriptは書きやすい。もう戻りたくない。
  • ESLintを導入してコーディング規約を強制した。おかげで比較的高品質のコードを終始簡単に弄るすことができた
  • Bootstrapに頼りきりだった割にUIが雑で残念
  • 一応LESSも導入したが特に使いこなせてない
  • テスト(ユニット,E2E)を書きたかったが、その余裕がなかった。そのうち書きたい
  • とにかく新しい技術/ツールで溢れた開発で楽しい1ヶ月半だった

次はTypeScript及びAngular2に手を付けてみたい。Angular2のほうが良さげであれば、本アプリを移植することも検討する。

MongoDBのよく使うコマンドメモ

初めてのMongoDBなので慣れるまではコレを見ながら一つ一つ丁寧に。

起動

$ mongo

終了

exit

データベースを一覧

show dbs();

データベースを選択(または新規作成)

use mydb;

コレクションの作成

db.createCollection(‘users’);

データベースのステータスを表示

db.status

データベースを削除

db.dropDatabase;

コレクションの一覧表示

show collections;

コレクション名を変更

db.users.renameCollection(“customers”);

コレクションを削除

db.users.drop();

コレクションにデータを挿入

db.users.insert({name: ‘sasaki , score: 70});

JavaScriptを用いてデータを挿入

db.users.insert({score: Math.random()});

コレクションのデータを全件表示

db.users.find();

コレクションのデータを全て削除

db.users.remove({});

コレクションを抽出(teamが1の要素)

db.users.find({team: 1});

コレクションを抽出(scoreが50以上)

db.users.find({score: {$gte: 50}});

コレクションを抽出(名前にsを含む)

db.users.find({score: /s/});

コレクションを抽出(名前にsを含みかつ80点以上)

db.users.find({name: /s/ , score: {$gte: 80}});

コレクションを抽出(名前にsを含むか、80点以上)

db.users.find($or , [{name: /s/} , {score , {$gte: 80}}]);

得点順にソート

db.users.find({}).sort({score: 1})

出力件数を制限

db.users.find({}).limit(3)

先頭N件はスキップ

db.users.find({}).skip(3)

1件のみデータを取得

db.users.findOne({})

特定データを更新

db.users.update({name: ‘sasaki’} , {$set , {score: 100}});

条件に当てはまる全てのデータを更新

db.users.update({} , {$set: {score: 100}} , {multi: 1});

ダンプを作成

$ mongodump -d [collection_name] --out [output_path]

ダンプからの復元

$ mongorestore --drop [dump_file_path]

参考