初めに
初投稿です!
MongoDBを初めて触る機会があり、いろいろと詰まったことを忘れないために書き残します。
まだ初心者エンジニアなので、勘違い等あるかと思いますが、間違い等ありましたら、指摘していただけると勉強になります!
書いてることは基本的にはMongoDB公式Documentに載っているはずです。
コマンド
GET-find
シンプルな検索
db.コレクション名.find({key: value})の形で検索をする。find()とすると全件を取得する。
[sample]
db.Collection.find({key1:fuga})
And条件での検索
db.Collection.find({ key1:fuga, key2:hoge })
db.inventory.find( { $and: [ { key1: 10 }, { key2: 20 } ] } )
Or条件での検索
db.Collection.find({key1: [ fuga, hoge ] })
db.inventory.find( { $or: [ { key1: 10 }, { key2: 20 } ] } )
ソート
sort({Key名:1(ASC) or -1(DESC)})で表現される。複数条件も可。
db.Collection.find().sort({key1:1})
カウント
数値を入れるだけ。
db.Collection.find().limit(10)
オフセット
数値を入れるだけ。
db.Collectuon.find().skip(10)
INSERT-insert
Mongo
mongo特有のPrimaryKeyのようなものとして、_id(ObjectId)が自動で付与される。
また、Bsonの形式で保存される(このまま文字列として保存されるようなもの)ので、変数名を短くすると少し軽くなることもある(らしい)。
また、今回はInsertですが、InsertOneやInsertManyのコマンドも知っていると便利でした!
db.Collection.insert({'key1':'value'})
UPDATE-update
db.Collection.update({条件式},{セット内容})
db.Collection.update({key1:fuga},{$set: {key2:hogehoge}})
DELETE-delete
db.Collection.delete({条件式})
db.Collection.delete({key1:fuga})
AGGREGATEについて
Aggregateは集計用の関数です。
PipeLineとよばれる段階的な処理をする構造で、その処理の段階の単位をステージと表現されます。
※イメージ(配列の形であらわされており、1要素あたり1ステージ)
PipeLine[ Stage1, Stage2, Stage3]
複雑な検索、集計処理を行う場合、Aggregateを用いることになると思います。
このAggregateが使いこなせると、Mongoって便利やなぁ…ってなります。
Aggregateを使うとJoinっぽいことができます。Joinを通してAggregateの使い方を書き残します。
Joinがしたい
lookup
Aggregateのパイプラインステージの$lookupを使うと、MongoでJoinっぽいことができます。
簡単に言うと、ジョイン先のコレクションに対して、検索をして、その結果をasに書いた名前の配列としてジョイン元ドキュメントに追加します。
また、lookupにはジョイン先、すなわち検索先コレクションに対してPipeLineを使うことができます。その場合、少し書き方が違うため、双方のパターンの実装例を示しておきます。(PipeLineを使わない実装はPipeLineを使う実装を簡略化したものだと思われます。)
実装例
PipeLineを使わない(Join先に検索をしない)
db.Collection.aggregate([{$lookup:
from: <ジョイン先のコレクション名>,
localField: <ジョイン元の紐づけるためのField>,
foreignField: <ジョイン先の紐づけるためのField>,
as: <ジョイン情報の名前>
}])
PipeLineを使う(Join先に検索をする)
db.Collection.aggregate([
{
$lookup:{
from: <ジョイン先のコレクション名>,
localField: <ジョイン元の紐づけるためのField>,
foreignField: <ジョイン先の紐づけるためのField>,
as: <ジョイン情報の名前>
}
},
{
$unwind: $ + <ジョイン情報の名前>
}
])
unwind
上記のlookupで取得した結果は配列になっています。配列に対する検索をする場合、$unwindを使って、配列を展開する必要があります。
展開するイメージとしては、下記のようになります。
unwindイメージ
{
_id: 123,
name: "伝説太郎",
hobby: ["釣り", "買い物", "キャンプ"]
}
↓↓↓
{
_id: 123,
name: "山田太郎",
hobby: "釣り"
},
{
_id: 123,
name: "山田太郎",
hobby: "買い物"
},
{
_id: 123,
name: "山田太郎",
hobby: "キャンプ"
},
実装例
※Mongo公式様のサンプルから引用です。
db.Collection.aggregate([
{
$lookup:{
from: <ジョイン先のコレクション名>,
localField: <ジョイン元の紐づけるためのField>,
foreignField: <ジョイン先の紐づけるためのField>,
as: <ジョイン情報の名前>
}
},
{
$unwind: $ + <ジョイン情報の名前>
}
])
db.Collection.aggregate([
{
$lookup:
{
from: <ジョイン先のコレクション名>,
// letはPipeLineで使用する変数を指定します
let: { order_item: "$item", order_qty: "$ordered" },
pipeline: [
{ $match:
{ $expr:
{ $and:
[
{ $eq: [ "$stock_item", "$$order_item" ] },
{ $gte: [ "$instock", "$$order_qty" ] }
]
}
}
},
{ $project: { stock_item: 0, _id: 0 } }
],
as: <ジョイン情報の名前>
}
}
])
match
ようやく検索です。findの時の書き方とそこまで変わりはありません。
$exprについては↓にちょっとだけ書きました。
{ $match:
{ $expr:
{ $and:
[
{ $eq: [ "$stock_item", "$$order_item" ] },
{ $gte: [ "$instock", "$$order_qty" ] }
]
}
}
}
比較演算子
同一ドキュメント内の変数を比較する場合
$exprを用いる。パイプラインステージのlookupの時の$letに近いもの。
実装例
$expr: {
$and: [
{ $eq: ["$hobby", "$name"] },
{ $gt: ["$age", "$date"] }]
}
おわりに
自分用の忘備録なので読みづらい文章で申し訳ないです。
私と同じ初心者さんで、わからないところや詰まってること等ありましたら、気軽にコメントしてください。
私にわかる範囲でならお答えします!
参考にさせていただいたページ様方
MongoDB コマンドメモとか書き
MongoDB で コレクションを結合する 方法
MongoDBのAggregationでRDBみたいな使い方