フロントエンドからはじめるMongoDB入門
まえおき
ポジショントーク
サーバーレスで JS で全部書けちゃうよ
データベースは MongoDB がおすすめだよ
Mongoose を使うとさらに便利だよ
影響を受けたもの
トランザクションが…とかスケーラビリティが…とか言われてるけど普通に使えてるやんという感想を抱いた
MongoDB とは
ドキュメント指向データベースの一つ
JSON ライクでスキーマレス
オープンソース(開発元は MongoDB Inc.)
ドキュメント指向データベースとは
いわゆる NoSQL の一つ
Key - Value 型の document と呼ばれる構造的データを JSON ライクな形式で表現
document の集合を collection として管理
RDBMS と NoSQL
関係データベース管理システム(RDBMS)以外のものが NoSQL と呼ばれる
RDBMS のモデルは表
計算やトランザクションなどのビジネスロジックに強み
NoSQL はより高速で柔軟なデータ操作に応える
XML や JSON なら JS でそのまま扱える
Next.js + MongoDB チュートリアル
以下の内容は基本的に次の動画の要約
Integrating MongoDB Into Your NextJS App
ソースコードはこちら
リファレンスとか
https://www.youtube.com/watch?v=aAupumVpqcE
ステップ1: MongoDB Atlas でアカウント作成
必須項目を入力して Get started free
Cloud のままにしておくと MongoDB Atlas で作成される
Organization、Project 作成
プロバイダ(今回は GCP の Tokyo リージョン)
Cluster 作成
Load Sample Dataset
今回は sample_airbnb を使う
CONNECTION
Setup connection security
ユーザー名
パスワード
Choose a connection method
Application
Connect
ステップ2: Next.js でプロジェクト作成
npx create-next-app --example with-mongodb nextbnb
.env.local に MONGODB_URL と MONGODB_DB を追加
code:.env
MONGODB_URL=mongodb+srv://<USERNAME>:<PASSWORD>@cluster0.tdm0q.mongodb.net/sample_airbnb?retryWrites=true&w=majority
MONGODB_DB=sample_airbnb
properties を取得して表示
property.js で sample_airbnb コレクションから20件取得するAPIを定義
code:pages/api/properties.ts
import { connectToDatabase } from '../../util/mongodb';
export default async function handler(req, res) {
const { db } = await connectToDatabase();
const data = await db.collection("listingsAndReviews").find({}).limit(20).toArray();
res.json(data);
}
index.js で property を取得し、map で展開
code:pages/index.ts
export default function Home({ properties }) {
// ...
{properties && properties.map(property => ()
// ...
)}
export async function getServerSideProps(context) {
const { db } = await connectToDatabase()
const data = await db.collection("listingsAndReviews").find({}).limit(50).toArray();
const properties = JSON.parse(JSON.stringify(data)); // ここはハック
const filtered = properties.map(property => { // エラーが出るので filter する
const price = JSON.parse(JSON.stringify(property.price))
return { // props
_id: property._id,
name: property.name,
image: property.images.picture_url,
address: property.address,
summary: property.summary,
guests: property.accommodates,
price: price.$numberDecimal,
}
})
return {
props: { properties: filtered },
}
}
ステップ3: 予約機能を追加
予約 API を作成
code:pages/api/book.js
import { connectToDatabase } from '../../util/mongodb';
export default async function handler(req, res) {
const { db } = await connectToDatabase();
const data = req.query;
const response = await db.collection("bookings").insertOne(data)
res.json(response);
}
code:pages/index.js
export default function Home({ properties }) {
// ...
const book = async (property) => {
const data = await fetch(http://localhost:3000/api/book?property_id=${property._id}&guest=Ado)
const res = await data.json();
console.log(res);
}
// ...
<div className="text-center py-2 my-2">
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 mr-5 rounded"
onClick={() => book(property)}
Book</button>
</div>
// ...
}
ステップ4: 検索機能を追加
sample_airbnb に検索機能を追加
Search Indexes
Create a Search Index
Configuration Method
Visual Editor
Collection and Index Name
Next
Review & Refine
Create Search Index
検索 API を作成
code:pages/api/search.js
import { connectToDatabase } from '../../util/mongodb';
export default async function handler(req, res) {
const { db } = await connectToDatabase();
const data = await db.collection("listingsAndReviews").aggregate([
{
$search: {
search: {
query: req.query.term, // 検索語
}
}
},
{
$project: { // 返却するフィールド
description: 1,
amenities: 1
}
},
{
$limit: 20 // 返却件数を指定
}
]).toArray(); // 最後に .toArray() しないと壊れる
res.json(data);
}
Tips: MongoDB Node Driver(Vanilla) vs Mongoose
Mongoose とは
MongoDB の Node.js 向けラッパー
ODM (ORM みたいなもの)の一種
スキーマが定義できたりする
どっちがいいの
Mongoose によって若干書きやすくなる
スケーラビリティを考えると、スキーマを定義できる Mongoose に軍配
ただ Mongoose は現状 TypeScript との噛み合わせが微妙という話がある
今回は MongoDB の実際の仕組みがわかりやすいよう Vanilla で記述した
次回
Express + Mongoose 使う編(未定)
もうちょっと知見がたまったら
感想コーナー
umamichi.icon パフォーマンスってどうなんだろう・・?
nishiyamayudai.icon NoSQL 自体は高速で大量のスループットが比較的得意でビッグデータに最適とか言われてる気がします。あとは Node なり Java なりのフレームワークそのものの性能で律速しそうですね
tsuzakitakehiro.iconラボでMongo使ってるのか気になりますね
nishiyamayudai.icon RDBMS と NoSQL の使い分けはあって、後者は AWS 使ってるのでそのまま DynamoDB 採用みたいになってそうです。MongoDB 利用例あるんですかね?
👍 Yuki Agatsuma YukiAgatsuma.icon がいいねしました on 2021/4/7