LoginSignup
0
1

More than 3 years have passed since last update.

Mongoコマンドとか初心者が苦しんだ所を書き残す。

Posted at

初めに

初投稿です!
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みたいな使い方

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1