「MongoDB」の版間の差分
ナビゲーションに移動
検索に移動
| (同じ利用者による、間の144版が非表示) | |||
| 1行目: | 1行目: | ||
==MongoDB== | ==MongoDB== | ||
{{amazon|B07BGC4MJ1}} | {{amazon|B07BGC4MJ1}} | ||
| + | |||
| + | [https://docs.mongodb.com/manual/ マニュアル] | ||
===ドキュメント指向データベース=== | ===ドキュメント指向データベース=== | ||
| + | ---- | ||
| + | ====スキーマレス==== | ||
| + | ---- | ||
*スキーマを定義しなくても利用できる | *スキーマを定義しなくても利用できる | ||
| + | *スキーマレスのため保守性が高い | ||
| + | *JSON方式でデータを保持 | ||
| + | *テーブルのことはコレクションと呼ぶ | ||
| + | ====パフォーマンス==== | ||
| + | ---- | ||
| + | *機能制限により、高パフォーマンスを実現 | ||
| + | *トランザクションがない | ||
| + | **処理速度がかなり高速 | ||
| + | *大量データの高速処理に向く | ||
| + | *スケールアウトが簡単な設定で可能 | ||
| + | ====操作感==== | ||
| + | ---- | ||
| + | *RDBと似た操作 | ||
*複雑な検索条件を利用できる | *複雑な検索条件を利用できる | ||
| + | ===インストール=== | ||
| + | ---- | ||
| + | *https://docs.mongodb.com/manual/installation/ | ||
| + | ====[[Ubuntu]]==== | ||
| + | ---- | ||
| + | *[https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/ コミュニティエディション] | ||
| + | |||
| + | <pre> | ||
| + | ubuntu@puli-mon:~$ cat /etc/os-release | ||
| + | NAME="Ubuntu" | ||
| + | VERSION="20.04.2 LTS (Focal Fossa)" | ||
| + | : | ||
| + | ubuntu@puli-mon:~$ wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add - | ||
| + | OK | ||
| + | ubuntu@puli-mon:~$ echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list | ||
| + | ubuntu@puli-mon:~$ sudo apt-get update | ||
| + | ubuntu@puli-mon:~$ sudo apt-get install -y mongodb-org | ||
| + | </pre> | ||
| + | =====ディレクトリ===== | ||
| + | ---- | ||
| + | {| class="wikitable" | ||
| + | |- | ||
| + | ! scope="col"| 種類 | ||
| + | ! scope="col"| 場所 | ||
| + | ! scope="col"| 備考 | ||
| + | |- | ||
| + | | データ | ||
| + | | /var/lib/mongodb | ||
| + | | | ||
| + | |- | ||
| + | | ログ | ||
| + | | /var/log/mongodb | ||
| + | | | ||
| + | |- | ||
| + | | 設定 | ||
| + | | /etc/mongod.conf | ||
| + | | | ||
| + | |- | ||
| + | |} | ||
| + | =====開始===== | ||
| + | ---- | ||
| + | <pre> | ||
| + | ubuntu@puli-mon:/etc$ sudo systemctl start mongod | ||
| + | </pre> | ||
| + | *失敗する場合 | ||
| + | <pre> | ||
| + | sudo systemctl daemon-reload | ||
| + | </pre> | ||
| + | =====リモートホストから接続===== | ||
| + | ---- | ||
| + | *デフォルトでは、localhostからのみ接続可能なため、bindIp の行を変更 | ||
| + | *$ sudo vi /etc/mongod.conf | ||
| + | <pre> | ||
| + | # network interfaces | ||
| + | net: | ||
| + | port: 27017 | ||
| + | # bindIp: 127.0.0.1 | ||
| + | bindIp: 0.0.0.0 | ||
| + | </pre> | ||
| + | ===設定=== | ||
| + | ---- | ||
| + | */etc/momgod.conf | ||
| + | *[http://docs.mongodb.org/manual/reference/configuration-options/ リファレンス] | ||
| + | |||
| + | |||
| + | ====systemlog==== | ||
| + | {| class="wikitable" | ||
| + | |- | ||
| + | ! scope="col"| パラメータ | ||
| + | ! scope="col"| 内容 | ||
| + | ! scope="col"| 備考 | ||
| + | |- | ||
| + | | destination | ||
| + | | ログの送り先、fileまたはsyslogを指定 | ||
| + | | | ||
| + | |- | ||
| + | | path | ||
| + | | ログを出力するファイル | ||
| + | | | ||
| + | |- | ||
| + | | logAppend | ||
| + | | trueの場合、ログを追記 | ||
| + | | | ||
| + | |- | ||
| + | | logRotage | ||
| + | | ログローテーション。renameもしくはreopen | ||
| + | | | ||
| + | |- | ||
| + | |} | ||
| + | |||
| + | ====storage==== | ||
| + | {| class="wikitable" | ||
| + | |- | ||
| + | ! scope="col"| パラメータ | ||
| + | ! scope="col"| 内容 | ||
| + | ! scope="col"| 備考 | ||
| + | |- | ||
| + | |||
| + | | dbPath | ||
| + | | データファイル保存先 | ||
| + | | | ||
| + | |- | ||
| + | | journal enabled | ||
| + | | ジャーナルを使用するかどうか | ||
| + | | | ||
| + | |- | ||
| + | | engine | ||
| + | | ストレージエンジンを指定 | ||
| + | | | ||
| + | |- | ||
| + | | | ||
| + | *wiredTiger: | ||
| + | **engineConfig: | ||
| + | ***cacheSizeGB: | ||
| + | | 使用するメモリのキャッシュサイズ | ||
| + | | | ||
| + | |- | ||
| + | | | ||
| + | *wiredTiger: | ||
| + | **collectionConfig: | ||
| + | ***blockCompressor: | ||
| + | | 格納データを圧縮できる。圧縮率を指定できる | ||
| + | *none:圧縮しない | ||
| + | *snappy:圧縮する | ||
| + | *zlib:snappyより高圧縮率で圧縮 | ||
| + | | | ||
| + | |- | ||
| + | | | ||
| + | | | ||
| + | | | ||
| + | |- | ||
| + | | | ||
| + | | | ||
| + | | | ||
| + | |- | ||
| + | | | ||
| + | | | ||
| + | | | ||
| + | |- | ||
| + | | | ||
| + | | | ||
| + | | | ||
| + | |- | ||
| + | |} | ||
| + | |||
| + | ===monogoシェルの実行=== | ||
| + | ---- | ||
| + | <pre> | ||
| + | ubuntu@puli-mon:/etc$ mongo | ||
| + | MongoDB shell version v4.4.6 | ||
| + | connecting to: mongodb://127.0.0.1:27017/? | ||
| + | : | ||
| + | --- | ||
| + | > | ||
| + | </pre> | ||
| + | |||
| + | ==GUI== | ||
| + | ===[https://www.mongodb.com/products/compass MongaDB Compass]=== | ||
| + | ---- | ||
| + | ===[https://robomongo.org/ Robo 3T]=== | ||
| + | ---- | ||
| + | *https://robomongo.org/download | ||
| + | *Only 3T | ||
| + | [[File:mongodb_gui_t3_download.png|500px]] | ||
| + | *起動 | ||
| + | [[File:mongodb_gui_t3.png|500px]] | ||
| + | |||
| + | ==データベース== | ||
| + | ===データベース作成=== | ||
| + | ---- | ||
| + | *use で作成 | ||
| + | <pre> | ||
| + | > use testdb | ||
| + | switched to db testdb | ||
| + | </pre> | ||
| + | |||
| + | *db。dろpDatabase() でカレントDBを削除 | ||
| + | |||
| + | ===コレクションを作成=== | ||
| + | ---- | ||
| + | <pre> | ||
| + | > db.createCollection("testDoc") | ||
| + | { "ok" : 1 } | ||
| + | </pre> | ||
| + | |||
| + | *一覧を確認 | ||
| + | <pre> | ||
| + | > show dbs | ||
| + | admin 0.000GB | ||
| + | config 0.000GB | ||
| + | local 0.000GB | ||
| + | testdb 0.000GB | ||
| + | </pre> | ||
| + | |||
| + | ===ドキュメントの登録=== | ||
| + | ---- | ||
| + | *testDocは、コレクション | ||
| + | <pre> | ||
| + | > db.testDoc.insertOne( | ||
| + | ... {name:"Foo",value:"Bar"} | ||
| + | ... ) | ||
| + | { | ||
| + | "acknowledged" : true, | ||
| + | "insertedId" : ObjectId("609f57392efac2b731a534eb") | ||
| + | } | ||
| + | </pre> | ||
| + | ===検索=== | ||
| + | ---- | ||
| + | *find | ||
| + | <pre> | ||
| + | > db.testDoc.find() | ||
| + | { "_id" : ObjectId("609f57392efac2b731a534eb"), "name" : "Foo", "value" : "Bar" } | ||
| + | </pre> | ||
| + | |||
| + | ===DB統計=== | ||
| + | ---- | ||
| + | <pre> | ||
| + | > db.stats() | ||
| + | { | ||
| + | "db" : "testdb", | ||
| + | "collections" : 1, // コレクション数 | ||
| + | "views" : 0, | ||
| + | "objects" : 1, | ||
| + | "avgObjSize" : 51, | ||
| + | "dataSize" : 51, // 圧縮前データサイズ | ||
| + | "storageSize" : 20480, | ||
| + | "indexes" : 1, // インデックス数 | ||
| + | "indexSize" : 20480, // インデックスデータ量 | ||
| + | "totalSize" : 40960, | ||
| + | "scaleFactor" : 1, | ||
| + | "fsUsedSize" : 2561937408, | ||
| + | "fsTotalSize" : 20629221376, | ||
| + | "ok" : 1 | ||
| + | } | ||
| + | </pre> | ||
| + | ==コレクション== | ||
| + | {| class="wikitable" | ||
| + | |- | ||
| + | ! scope="col"| 種類 | ||
| + | ! scope="col"| コマンド | ||
| + | ! scope="col"| 例 | ||
| + | |- | ||
| + | | コレクションの作成 | ||
| + | | db.createCollection(コレクション名) | ||
| + | | db.createCollection("testCollection") | ||
| + | |- | ||
| + | | コレクションの一覧表示 | ||
| + | | show collections | ||
| + | | | ||
| + | |- | ||
| + | | 統計情報表示 | ||
| + | | db.collection.stats() | ||
| + | | | ||
| + | |- | ||
| + | | コレクションの削除 | ||
| + | | db.collection.drop() | ||
| + | | db.testCollection.drop | ||
| + | |- | ||
| + | |} | ||
| + | ===Cappedコレクション=== | ||
| + | ---- | ||
| + | *コレクションに入れられるデータの上限を設定 | ||
| + | *データ量が上限になると、古いドキュメントから削除されていく | ||
| + | *レプリカセットでは、Cappedコレクションを使ってデータを同期している | ||
| + | *createCollection のオプションを変更して作成 | ||
| + | <pre> | ||
| + | db.createCollection( | ||
| + | "コレクション名", | ||
| + | [capped: true, size: データ上限(バイト)サイズ] | ||
| + | ) | ||
| + | </pre> | ||
| + | ==登録== | ||
| + | {| class="wikitable" | ||
| + | |- | ||
| + | ! scope="col"| 方法 | ||
| + | ! scope="col"| コマンド | ||
| + | ! scope="col"| 例 | ||
| + | |- | ||
| + | | 1件登録 | ||
| + | | db.collection.insertOne({...}) | ||
| + | | db.testCollection.insertOne({key:"1",value:"a"}) | ||
| + | |- | ||
| + | | 複数登録 | ||
| + | | db.collection.insertMany([ | ||
| + | {...}, | ||
| + | {...} | ||
| + | ]) | ||
| + | | db.testCollection.insertMany([ | ||
| + | {key:2,value:"b"}, | ||
| + | {key:3,value:"c"} | ||
| + | ]) | ||
| + | |} | ||
| + | |||
| + | ==検索== | ||
| + | {| class="wikitable" | ||
| + | |- | ||
| + | ! scope="col"| 方法 | ||
| + | ! scope="col"| コマンド | ||
| + | ! scope="col"| 例 | ||
| + | |- | ||
| + | | 全件 | ||
| + | | db.collection.find() | ||
| + | | db.testCollection.find() | ||
| + | |- | ||
| + | | フィールドを指定 | ||
| + | | db.collection.find( | ||
| + | {検索条件}, | ||
| + | {key1:0,kye2:1,...} | ||
| + | ) | ||
| + | //key1を非表示、key2を表示 | ||
| + | |db.testCollection.find( | ||
| + | {key:2}, | ||
| + | {_id:0,key:1,value:1} | ||
| + | ) | ||
| + | |- | ||
| + | | 完全一致 | ||
| + | | {key:value} | ||
| + | | | ||
| + | |- | ||
| + | | 部分一致 | ||
| + | | {key:/value/} | ||
| + | | | ||
| + | |- | ||
| + | | 前方一致 | ||
| + | | {key:/^value/} | ||
| + | | | ||
| + | |- | ||
| + | | 後方一致 | ||
| + | | {key:/value$/} | ||
| + | | | ||
| + | |- | ||
| + | | 以下 | ||
| + | | {key:{$lte:value}} | ||
| + | | | ||
| + | |- | ||
| + | | 未満 | ||
| + | | {key:{$lt:value}} | ||
| + | | | ||
| + | |- | ||
| + | | 以上 | ||
| + | | {key:{$gte:value}} | ||
| + | | | ||
| + | |- | ||
| + | | より大きい | ||
| + | | {key:{$gt:value}} | ||
| + | | | ||
| + | |- | ||
| + | | 範囲指定 | ||
| + | | {key:{$gte:value1, $lte:value2}} | ||
| + | | | ||
| + | |- | ||
| + | | and | ||
| + | | {$and:[ | ||
| + | {key1:value1}, | ||
| + | {key2:value2} | ||
| + | ]} | ||
| + | | | ||
| + | |- | ||
| + | | or | ||
| + | | {$or:[ | ||
| + | {key1:value1}, | ||
| + | {key2:value2} | ||
| + | ]} | ||
| + | | | ||
| + | |- | ||
| + | | null | ||
| + | | {key:null} | ||
| + | 以下が検索される | ||
| + | 1.データ型がNull | ||
| + | 2.フィールドなし | ||
| + | 3.undefined | ||
| + | | | ||
| + | |- | ||
| + | | フィールドの存在有無($exists) | ||
| + | | { key: {$exists: false}} | ||
| + | | | ||
| + | |- | ||
| + | | データ型を指定($type) | ||
| + | | {key:{$type:"null"}} | ||
| + | // Null型を指定して検索 | ||
| + | | | ||
| + | |- | ||
| + | | ソート | ||
| + | | db.collection.find().sort({...}) | ||
| + | // 1:昇順,-1:降順 | ||
| + | | db.testCollection.find().sort( | ||
| + | {key:-1} | ||
| + | ) | ||
| + | |- | ||
| + | | 件数 | ||
| + | | db.collection.find().count() | ||
| + | | | ||
| + | |- | ||
| + | |} | ||
| + | |||
| + | ==更新== | ||
| + | {| class="wikitable" | ||
| + | |- | ||
| + | ! scope="col"| 方法 | ||
| + | ! scope="col"| コマンド | ||
| + | ! scope="col"| 例 | ||
| + | |- | ||
| + | | 1件ドキュメントを更新 | ||
| + | | db.collection.updateOne( | ||
| + | {検索条件}, | ||
| + | {$set:{更新内容}} | ||
| + | ) | ||
| + | | 一致するデータが複数あっても、1件しか更新されない | ||
| + | db.testCollection.updateOne( | ||
| + | {key:"1"}}, | ||
| + | {$set:{value2:"v2"}} | ||
| + | ) | ||
| + | |- | ||
| + | | 複数件のドキュメントを更新 | ||
| + | | db.collection.updateMany( | ||
| + | {検索条件}, | ||
| + | {$set:{更新内容}} | ||
| + | ) | ||
| + | | 更新に一致したドキュメントを全て更新 | ||
| + | db.testCollection.updateMany( | ||
| + | {key:{$lt:4}}, | ||
| + | {$set:{value2:"v2"}} | ||
| + | ) | ||
| + | |- | ||
| + | | ドキュメントの置き換え | ||
| + | | db.collection.replaceOne( | ||
| + | {検索条件} | ||
| + | {更新内容} | ||
| + | ) | ||
| + | | 入れ替えられるのは1件だけ | ||
| + | db.testCollection.replaceOne( | ||
| + | {key:"1"}, | ||
| + | {key:1, value:"a", value2:"v1"} | ||
| + | ) | ||
| + | |- | ||
| + | | フィールド名を変更 | ||
| + | | $rename 旧Key:"新Key" | ||
| + | | db.testCollection.updateMany( | ||
| + | {}, | ||
| + | {$rename:{value:"val1"}} | ||
| + | ) | ||
| + | |- | ||
| + | | 配列のインデックス | ||
| + | | フィールド名.n | ||
| + | | {$set:{"ary.3":"hoge"}} | ||
| + | |- | ||
| + | | 登録または更新(upsert) | ||
| + | | db.collection.updateOne( | ||
| + | {検索条件}, | ||
| + | {更新内容}, | ||
| + | {upsert: true} | ||
| + | ) | ||
| + | | | ||
| + | |- | ||
| + | |} | ||
| + | ===フィールドを新規追加=== | ||
| + | ---- | ||
| + | *既存のフィールド($RaceId.Year ・・・)を接続して、新しいフィールド(_RaceId)を追加 | ||
| + | <pre> | ||
| + | db.H1.update( | ||
| + | {"_id": ObjectId("60a7c66cb07a3cd94da9958c") }, | ||
| + | [ | ||
| + | {"$set": { "_RaceId": { $concat: [ "$RaceId.Year", "-", "$RaceId.MonthDay", "-","$RaceId.JyoCD", "-","$RaceId.Kaiji", "-","$RaceId.Nichiji", "-","$RaceId.RaceNum" ] } } } | ||
| + | ] | ||
| + | ) | ||
| + | </pre> | ||
| + | |||
| + | ==削除== | ||
| + | {| class="wikitable" | ||
| + | |- | ||
| + | ! scope="col"| 方法 | ||
| + | ! scope="col"| コマンド | ||
| + | ! scope="col"| 例 | ||
| + | |- | ||
| + | | 1件削除 | ||
| + | | db.collection.deleteOne({検索条件}) | ||
| + | | 複数件一致しても、削除されるのは1件 | ||
| + | |- | ||
| + | | 複数件削除 | ||
| + | | db.collection.deleteMany({検索条件}) | ||
| + | | | ||
| + | |- | ||
| + | |} | ||
| + | ==集計== | ||
| + | *findで集計はできないため、aggregationメソッドを利用する | ||
| + | *$group に 集計対象 _id は必須 | ||
| + | *全体の集計を行うときは、_id:null とする | ||
| + | {| class="wikitable" | ||
| + | |- | ||
| + | ! scope="col"| 集計 | ||
| + | ! scope="col"| 集計関数 | ||
| + | ! scope="col"| 例 | ||
| + | |- | ||
| + | | 最大値 | ||
| + | | $max | ||
| + | | | ||
| + | |- | ||
| + | | 最小値 | ||
| + | | $min | ||
| + | | | ||
| + | |- | ||
| + | | 平均値 | ||
| + | | $avg | ||
| + | | | ||
| + | |- | ||
| + | | | ||
| + | | | ||
| + | | | ||
| + | |- | ||
| + | |} | ||
| + | ===簡単な集計=== | ||
| + | ---- | ||
| + | <pre> | ||
| + | db.collection.aggregate([ | ||
| + | { $match:{<検索条件>}}, | ||
| + | { $group:{ _id::"$<集計フィールド>",<集計結果表示名>:{<集計関数>:"$集計フィールド"}}} | ||
| + | ]) | ||
| + | </pre> | ||
| + | ====基本==== | ||
| + | **$group に 指定した _id フィールドごとに集計を行う | ||
| + | **"$フィールド名"と入力する | ||
| + | **集計関数 $sumを指定、複数指定も可能 | ||
| + | <pre> | ||
| + | db.getCollection("O1").aggregate([ | ||
| + | { $match: { 'head.MakeDate.Year':{ '$gt':'2010', '$lt':'2020' }} }, | ||
| + | { $group: { _id:'$head.MakeDate.Year', tosu: {'$sum':{ '$toInt': '$TorokuTosu' }}} } | ||
| + | ]) | ||
| + | </pre> | ||
| + | [[File:mongo_aggregate_sum.png|600px]] | ||
| + | ====グループ化のあとに、さらに条件を適用==== | ||
| + | <pre> | ||
| + | db.getCollection("O1").aggregate([ | ||
| + | { $match: { 'head.MakeDate.Year':{ '$gt':'2010', '$lt':'2020' }} }, | ||
| + | { $group: { _id:'$head.MakeDate.Year', tosu: {'$sum':{ '$toInt': '$TorokuTosu' }}} }, | ||
| + | { $match: { 'tosu' : { '$gt': 49000 }} } | ||
| + | ]) | ||
| + | </pre> | ||
| + | [[File:mongo_aggregate_sum2.png|600px]] | ||
| + | |||
| + | ====集計関数を複数同時に使用==== | ||
| + | <pre> | ||
| + | db.getCollection("O1").aggregate([ | ||
| + | { $match: { 'head.MakeDate.Year':{ '$gt':'2010', '$lt':'2020' }} }, | ||
| + | { $group: { _id:'$head.MakeDate.Year', | ||
| + | tosu_total: {'$sum':{ '$toInt': '$TorokuTosu' }}, | ||
| + | tosu_max: {'$max':{ '$toInt': '$TorokuTosu' }}, | ||
| + | tosu_min: {'$min':{ '$toInt': '$TorokuTosu' }}, | ||
| + | tosu_avg: {'$avg':{ '$toInt': '$TorokuTosu' }} }} | ||
| + | ]) | ||
| + | </pre> | ||
| + | [[File:mongo_aggregate_sum3.png|600px]] | ||
| + | ====グループごとの件数をカウント==== | ||
| + | *$sum:1 とする | ||
| + | <pre> | ||
| + | db.getCollection("O1").aggregate([ | ||
| + | { $match: { 'head.MakeDate.Year':{ '$gt':'2010', '$lt':'2020' }} }, | ||
| + | { $group: { _id:'$head.MakeDate.Year', | ||
| + | tosu_total: {'$sum':{ '$toInt': '$TorokuTosu' }}, | ||
| + | tosu_max: {'$max':{ '$toInt': '$TorokuTosu' }}, | ||
| + | tosu_min: {'$min':{ '$toInt': '$TorokuTosu' }}, | ||
| + | tosu_avg: {'$avg':{ '$toInt': '$TorokuTosu' }}, | ||
| + | tosu_cnt: {'$sum':1} }} | ||
| + | ]) | ||
| + | </pre> | ||
| + | ===コレクションの結合=== | ||
| + | ---- | ||
| + | *aggregationではコレクションを結合できる | ||
| + | *$lookup を利用する | ||
| + | <pre> | ||
| + | db.collection.aggregate([ | ||
| + | { $lookup:{ | ||
| + | from: "<結合先コレクション>", | ||
| + | localField:"<結合元の結合フィールド>", | ||
| + | foreginField:"<結合先の結合フィールド>", | ||
| + | as:"<結合先コレクションの別名>" | ||
| + | }} | ||
| + | ]) | ||
| + | </pre> | ||
| + | =====結合($lookup)===== | ||
| + | <pre> | ||
| + | db.RA.aggregate([ | ||
| + | { $lookup:{ | ||
| + | from:"SE", | ||
| + | localField:"_RaceId", | ||
| + | foreignField:"_RaceId", | ||
| + | as:"SE" | ||
| + | }} | ||
| + | ]) | ||
| + | </pre> | ||
| + | =====検索条件を指定して結合($match)===== | ||
| + | <pre> | ||
| + | db.RA.aggregate([ | ||
| + | { $match: { "_id" : ObjectId("60a7c617b07a3cd94da991b7") } }, // 検索条件 | ||
| + | { $lookup:{ | ||
| + | from:"SE", | ||
| + | localField:"_RaceId", | ||
| + | foreignField:"_RaceId", | ||
| + | as:"SE" | ||
| + | }} | ||
| + | ]) // 結合条件 | ||
| + | </pre> | ||
| + | =====表示フィールドの絞り込み($project) ===== | ||
| + | <pre> | ||
| + | db.RA.aggregate([ | ||
| + | { $match: { "_id" : ObjectId("60a7c617b07a3cd94da991b7") } }, | ||
| + | { $lookup:{ | ||
| + | from:"SE", | ||
| + | localField:"_RaceId", | ||
| + | foreignField:"_RaceId", | ||
| + | as:"SE" | ||
| + | }}, | ||
| + | { $project: { | ||
| + | "RaceInfo":1, | ||
| + | "JyokenInfo":1, | ||
| + | "SE":1 | ||
| + | }} // 表示フィールドの絞り込み | ||
| + | ]) | ||
| + | </pre> | ||
| + | [[File:mongo_lookup.png|600px]] | ||
| + | |||
| + | ===一括高速処理(Bulk)=== | ||
| + | ---- | ||
| + | *Bulk操作には大きく2つのタイプ | ||
| + | **順次処理:登録の順番に意味があるフィールドを持つ場合に使用 | ||
| + | **並列処理:順番に関係なく処理を実行 | ||
| + | ====一括登録(insert)==== | ||
| + | ---- | ||
| + | <pre> | ||
| + | var bulk = db.collection.initializeOrderBulkOp(); //Bulkの実行タイプを指定 | ||
| + | bulk.insert({<登録ドキュメント>}); | ||
| + | bulk.execute(); // Bulkの実行 | ||
| + | </pre> | ||
| + | ====一括更新(update)==== | ||
| + | ---- | ||
| + | <pre> | ||
| + | var bulk = db.H6.initializeUnorderedBulkOp(); | ||
| + | bulk.find({}).update( | ||
| + | [{"$set": { "_RaceId": { $concat: [ "$RaceId.Year", "-", "$RaceId.MonthDay", "-","$RaceId.JyoCD", "-","$RaceId.Kaiji", "-","$RaceId.Nichiji", "-","$RaceId.RaceNum" ] } } }] | ||
| + | ); | ||
| + | bulk.execute(); | ||
| + | </pre> | ||
| + | |||
| + | ====一括登録または更新(upsert)==== | ||
| + | ---- | ||
| + | ====一括削除(remove)==== | ||
| + | ---- | ||
| + | |||
| + | ==インデックス== | ||
| + | ===作成=== | ||
| + | ---- | ||
| + | *1:昇順、-1:降順 | ||
| + | <pre> | ||
| + | db.collection.createIndex( | ||
| + | { key1:1, key2:-1, ・・・}, | ||
| + | { <インデックスオプション>} | ||
| + | ) | ||
| + | </pre> | ||
| + | ====インデックスオプション==== | ||
| + | ---- | ||
| + | {| class="wikitable" | ||
| + | |- | ||
| + | ! scope="col"| 項目 | ||
| + | ! scope="col"| 説明 | ||
| + | ! scope="col"| 備考 | ||
| + | |- | ||
| + | | background | ||
| + | | バックグラウンド実行 | ||
| + | | データ大量時、アプリケーションへの応答遅延防止など | ||
| + | |- | ||
| + | | name | ||
| + | | インデックス名を指定 | ||
| + | | | ||
| + | |- | ||
| + | | unique | ||
| + | | ユニークインデックス | ||
| + | | null不可 | ||
| + | |- | ||
| + | | partialFilterExpression | ||
| + | | フィルタを作成し一致したドキュメントの部分インデックスを作成 | ||
| + | | 以下を指定できる | ||
| + | *等式(key: value , $eq) | ||
| + | *$exists | ||
| + | *$gt, $gte, $lt, $lte | ||
| + | *$type ・$and | ||
| + | |- | ||
| + | |} | ||
| + | ====インデックス種類==== | ||
| + | ---- | ||
| + | {| class="wikitable" | ||
| + | |- | ||
| + | ! scope="col"| 種類 | ||
| + | ! scope="col"| 説明 | ||
| + | ! scope="col"| 備考 | ||
| + | |- | ||
| + | | デフォルトインデックス | ||
| + | | _idフィールドに作成される | ||
| + | | 削除できない | ||
| + | |- | ||
| + | | テキストインデックス | ||
| + | | 文字列コンテンツに対するテキスト検索クエリをサポートするテキストインデックスを作成 | ||
| + | | 作成には、keyに"text"を指定する | ||
| + | <pre> | ||
| + | db.collection.createIndex({ key: "text" }) | ||
| + | </pre> | ||
| + | |- | ||
| + | | TTLインデックス | ||
| + | | 特定の時間または時刻にドキュメントを自動削除するために利用する | ||
| + | | Date型、Date型を含む配列、expireAfterSecondsが経過したドキュメントを自動で削除する | ||
| + | <pre> | ||
| + | db.collection.createIndex({ | ||
| + | {key: 1}, | ||
| + | {expireAfterSeconds:<秒数>} | ||
| + | }) | ||
| + | </pre> | ||
| + | |- | ||
| + | | ハッシュインデックス | ||
| + | | フィールド値のハッシュをインデックスにする | ||
| + | | ランダム分布をも持つが、値一致飲みサポート | ||
| + | |- | ||
| + | |地理的インデックス | ||
| + | |プレーンジオメトリ、球面ジオメトリ | ||
| + | | | ||
| + | |} | ||
| + | |||
| + | ===確認=== | ||
| + | ---- | ||
| + | <pre> | ||
| + | db.collection.getIndexes() | ||
| + | </pre> | ||
| + | ===削除=== | ||
| + | ---- | ||
| + | *上記で確認した、nameを指定する | ||
| + | <pre> | ||
| + | db.collection.dropIndex("インデックス名") | ||
| + | </pre> | ||
| + | ===再構築=== | ||
| + | ---- | ||
| + | <pre> | ||
| + | db.collection.reIndex() | ||
| + | </pre> | ||
| + | |||
| + | ==Tips== | ||
| + | ===stringをintに変換=== | ||
| + | <pre> | ||
| + | db.getCollection('O1').find({},{tosu:{ '$toInt': '$TorokuTosu' }}) | ||
| + | </pre> | ||
| + | [[File:mongo_to_into.png|500px]] | ||
| + | |||
| + | ==プログラミング== | ||
| + | ===[[C Sharp|C#]]=== | ||
| + | ---- | ||
| + | *[https://mongodb.github.io/mongo-csharp-driver/2.8/apidocs/html/R_Project_CSharpDriverDocs.htm C# MongoDriver] | ||
| + | ====Insert==== | ||
| + | ---- | ||
| + | <pre> | ||
| + | using MongoDB.Driver; | ||
| + | : | ||
| + | var client = new MongoClient("mongodb://puli-mon.local"); | ||
| + | var mongoDb = client.GetDatabase("jra"); | ||
| + | var colH1 = mongoDb.GetCollection<JV_H1_HYOSU_ZENKAKE>("h1"); | ||
| + | : | ||
| + | colH1.InsertOne(rec); | ||
| + | </pre> | ||
2021年6月16日 (水) 00:04時点における最新版
MongoDB
ドキュメント指向データベース
スキーマレス
- スキーマを定義しなくても利用できる
- スキーマレスのため保守性が高い
- JSON方式でデータを保持
- テーブルのことはコレクションと呼ぶ
パフォーマンス
- 機能制限により、高パフォーマンスを実現
- トランザクションがない
- 処理速度がかなり高速
- 大量データの高速処理に向く
- スケールアウトが簡単な設定で可能
操作感
- RDBと似た操作
- 複雑な検索条件を利用できる
インストール
Ubuntu
ubuntu@puli-mon:~$ cat /etc/os-release NAME="Ubuntu" VERSION="20.04.2 LTS (Focal Fossa)" : ubuntu@puli-mon:~$ wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add - OK ubuntu@puli-mon:~$ echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list ubuntu@puli-mon:~$ sudo apt-get update ubuntu@puli-mon:~$ sudo apt-get install -y mongodb-org
ディレクトリ
| 種類 | 場所 | 備考 |
|---|---|---|
| データ | /var/lib/mongodb | |
| ログ | /var/log/mongodb | |
| 設定 | /etc/mongod.conf |
開始
ubuntu@puli-mon:/etc$ sudo systemctl start mongod
- 失敗する場合
sudo systemctl daemon-reload
リモートホストから接続
- デフォルトでは、localhostからのみ接続可能なため、bindIp の行を変更
- $ sudo vi /etc/mongod.conf
# network interfaces net: port: 27017 # bindIp: 127.0.0.1 bindIp: 0.0.0.0
設定
- /etc/momgod.conf
- リファレンス
systemlog
| パラメータ | 内容 | 備考 |
|---|---|---|
| destination | ログの送り先、fileまたはsyslogを指定 | |
| path | ログを出力するファイル | |
| logAppend | trueの場合、ログを追記 | |
| logRotage | ログローテーション。renameもしくはreopen |
storage
| パラメータ | 内容 | 備考 |
|---|---|---|
| dbPath | データファイル保存先 | |
| journal enabled | ジャーナルを使用するかどうか | |
| engine | ストレージエンジンを指定 | |
|
使用するメモリのキャッシュサイズ | |
|
格納データを圧縮できる。圧縮率を指定できる
|
|
monogoシェルの実行
ubuntu@puli-mon:/etc$ mongo
MongoDB shell version v4.4.6
connecting to: mongodb://127.0.0.1:27017/?
:
---
>
GUI
MongaDB Compass
Robo 3T
- https://robomongo.org/download
- Only 3T
- 起動
データベース
データベース作成
- use で作成
> use testdb switched to db testdb
- db。dろpDatabase() でカレントDBを削除
コレクションを作成
> db.createCollection("testDoc")
{ "ok" : 1 }
- 一覧を確認
> show dbs admin 0.000GB config 0.000GB local 0.000GB testdb 0.000GB
ドキュメントの登録
- testDocは、コレクション
> db.testDoc.insertOne(
... {name:"Foo",value:"Bar"}
... )
{
"acknowledged" : true,
"insertedId" : ObjectId("609f57392efac2b731a534eb")
}
検索
- find
> db.testDoc.find()
{ "_id" : ObjectId("609f57392efac2b731a534eb"), "name" : "Foo", "value" : "Bar" }
DB統計
> db.stats()
{
"db" : "testdb",
"collections" : 1, // コレクション数
"views" : 0,
"objects" : 1,
"avgObjSize" : 51,
"dataSize" : 51, // 圧縮前データサイズ
"storageSize" : 20480,
"indexes" : 1, // インデックス数
"indexSize" : 20480, // インデックスデータ量
"totalSize" : 40960,
"scaleFactor" : 1,
"fsUsedSize" : 2561937408,
"fsTotalSize" : 20629221376,
"ok" : 1
}
コレクション
| 種類 | コマンド | 例 |
|---|---|---|
| コレクションの作成 | db.createCollection(コレクション名) | db.createCollection("testCollection") |
| コレクションの一覧表示 | show collections | |
| 統計情報表示 | db.collection.stats() | |
| コレクションの削除 | db.collection.drop() | db.testCollection.drop |
Cappedコレクション
- コレクションに入れられるデータの上限を設定
- データ量が上限になると、古いドキュメントから削除されていく
- レプリカセットでは、Cappedコレクションを使ってデータを同期している
- createCollection のオプションを変更して作成
db.createCollection( "コレクション名", [capped: true, size: データ上限(バイト)サイズ] )
登録
| 方法 | コマンド | 例 |
|---|---|---|
| 1件登録 | db.collection.insertOne({...}) | db.testCollection.insertOne({key:"1",value:"a"}) |
| 複数登録 | db.collection.insertMany([
{...}, {...} ]) |
db.testCollection.insertMany([
{key:2,value:"b"}, {key:3,value:"c"} ]) |
検索
| 方法 | コマンド | 例 |
|---|---|---|
| 全件 | db.collection.find() | db.testCollection.find() |
| フィールドを指定 | db.collection.find(
{検索条件}, {key1:0,kye2:1,...} ) //key1を非表示、key2を表示 |
db.testCollection.find(
{key:2}, {_id:0,key:1,value:1} ) |
| 完全一致 | {key:value} | |
| 部分一致 | {key:/value/} | |
| 前方一致 | {key:/^value/} | |
| 後方一致 | {key:/value$/} | |
| 以下 | {key:{$lte:value}} | |
| 未満 | {key:{$lt:value}} | |
| 以上 | {key:{$gte:value}} | |
| より大きい | {key:{$gt:value}} | |
| 範囲指定 | {key:{$gte:value1, $lte:value2}} | |
| and | {$and:[
{key1:value1}, {key2:value2} ]} |
|
| or | {$or:[
{key1:value1}, {key2:value2} ]} |
|
| null | {key:null}
以下が検索される 1.データ型がNull 2.フィールドなし 3.undefined |
|
| フィールドの存在有無($exists) | { key: {$exists: false}} | |
| データ型を指定($type) | {key:{$type:"null"}}
// Null型を指定して検索 |
|
| ソート | db.collection.find().sort({...})
// 1:昇順,-1:降順 |
db.testCollection.find().sort(
{key:-1} ) |
| 件数 | db.collection.find().count() |
更新
| 方法 | コマンド | 例 |
|---|---|---|
| 1件ドキュメントを更新 | db.collection.updateOne(
{検索条件}, {$set:{更新内容}} ) |
一致するデータが複数あっても、1件しか更新されない
db.testCollection.updateOne( {key:"1"}}, {$set:{value2:"v2"}} ) |
| 複数件のドキュメントを更新 | db.collection.updateMany(
{検索条件}, {$set:{更新内容}} ) |
更新に一致したドキュメントを全て更新
db.testCollection.updateMany( {key:{$lt:4}}, {$set:{value2:"v2"}} ) |
| ドキュメントの置き換え | db.collection.replaceOne(
{検索条件} {更新内容} ) |
入れ替えられるのは1件だけ
db.testCollection.replaceOne( {key:"1"}, {key:1, value:"a", value2:"v1"} ) |
| フィールド名を変更 | $rename 旧Key:"新Key" | db.testCollection.updateMany(
{}, {$rename:{value:"val1"}} ) |
| 配列のインデックス | フィールド名.n | {$set:{"ary.3":"hoge"}} |
| 登録または更新(upsert) | db.collection.updateOne(
{検索条件}, {更新内容}, {upsert: true} ) |
フィールドを新規追加
- 既存のフィールド($RaceId.Year ・・・)を接続して、新しいフィールド(_RaceId)を追加
db.H1.update(
{"_id": ObjectId("60a7c66cb07a3cd94da9958c") },
[
{"$set": { "_RaceId": { $concat: [ "$RaceId.Year", "-", "$RaceId.MonthDay", "-","$RaceId.JyoCD", "-","$RaceId.Kaiji", "-","$RaceId.Nichiji", "-","$RaceId.RaceNum" ] } } }
]
)
削除
| 方法 | コマンド | 例 |
|---|---|---|
| 1件削除 | db.collection.deleteOne({検索条件}) | 複数件一致しても、削除されるのは1件 |
| 複数件削除 | db.collection.deleteMany({検索条件}) |
集計
- findで集計はできないため、aggregationメソッドを利用する
- $group に 集計対象 _id は必須
- 全体の集計を行うときは、_id:null とする
| 集計 | 集計関数 | 例 |
|---|---|---|
| 最大値 | $max | |
| 最小値 | $min | |
| 平均値 | $avg | |
簡単な集計
db.collection.aggregate([
{ $match:{<検索条件>}},
{ $group:{ _id::"$<集計フィールド>",<集計結果表示名>:{<集計関数>:"$集計フィールド"}}}
])
基本
- $group に 指定した _id フィールドごとに集計を行う
- "$フィールド名"と入力する
- 集計関数 $sumを指定、複数指定も可能
db.getCollection("O1").aggregate([
{ $match: { 'head.MakeDate.Year':{ '$gt':'2010', '$lt':'2020' }} },
{ $group: { _id:'$head.MakeDate.Year', tosu: {'$sum':{ '$toInt': '$TorokuTosu' }}} }
])
グループ化のあとに、さらに条件を適用
db.getCollection("O1").aggregate([
{ $match: { 'head.MakeDate.Year':{ '$gt':'2010', '$lt':'2020' }} },
{ $group: { _id:'$head.MakeDate.Year', tosu: {'$sum':{ '$toInt': '$TorokuTosu' }}} },
{ $match: { 'tosu' : { '$gt': 49000 }} }
])
集計関数を複数同時に使用
db.getCollection("O1").aggregate([
{ $match: { 'head.MakeDate.Year':{ '$gt':'2010', '$lt':'2020' }} },
{ $group: { _id:'$head.MakeDate.Year',
tosu_total: {'$sum':{ '$toInt': '$TorokuTosu' }},
tosu_max: {'$max':{ '$toInt': '$TorokuTosu' }},
tosu_min: {'$min':{ '$toInt': '$TorokuTosu' }},
tosu_avg: {'$avg':{ '$toInt': '$TorokuTosu' }} }}
])
グループごとの件数をカウント
- $sum:1 とする
db.getCollection("O1").aggregate([
{ $match: { 'head.MakeDate.Year':{ '$gt':'2010', '$lt':'2020' }} },
{ $group: { _id:'$head.MakeDate.Year',
tosu_total: {'$sum':{ '$toInt': '$TorokuTosu' }},
tosu_max: {'$max':{ '$toInt': '$TorokuTosu' }},
tosu_min: {'$min':{ '$toInt': '$TorokuTosu' }},
tosu_avg: {'$avg':{ '$toInt': '$TorokuTosu' }},
tosu_cnt: {'$sum':1} }}
])
コレクションの結合
- aggregationではコレクションを結合できる
- $lookup を利用する
db.collection.aggregate([
{ $lookup:{
from: "<結合先コレクション>",
localField:"<結合元の結合フィールド>",
foreginField:"<結合先の結合フィールド>",
as:"<結合先コレクションの別名>"
}}
])
結合($lookup)
db.RA.aggregate([
{ $lookup:{
from:"SE",
localField:"_RaceId",
foreignField:"_RaceId",
as:"SE"
}}
])
検索条件を指定して結合($match)
db.RA.aggregate([
{ $match: { "_id" : ObjectId("60a7c617b07a3cd94da991b7") } }, // 検索条件
{ $lookup:{
from:"SE",
localField:"_RaceId",
foreignField:"_RaceId",
as:"SE"
}}
]) // 結合条件
表示フィールドの絞り込み($project)
db.RA.aggregate([
{ $match: { "_id" : ObjectId("60a7c617b07a3cd94da991b7") } },
{ $lookup:{
from:"SE",
localField:"_RaceId",
foreignField:"_RaceId",
as:"SE"
}},
{ $project: {
"RaceInfo":1,
"JyokenInfo":1,
"SE":1
}} // 表示フィールドの絞り込み
])
一括高速処理(Bulk)
- Bulk操作には大きく2つのタイプ
- 順次処理:登録の順番に意味があるフィールドを持つ場合に使用
- 並列処理:順番に関係なく処理を実行
一括登録(insert)
var bulk = db.collection.initializeOrderBulkOp(); //Bulkの実行タイプを指定
bulk.insert({<登録ドキュメント>});
bulk.execute(); // Bulkの実行
一括更新(update)
var bulk = db.H6.initializeUnorderedBulkOp();
bulk.find({}).update(
[{"$set": { "_RaceId": { $concat: [ "$RaceId.Year", "-", "$RaceId.MonthDay", "-","$RaceId.JyoCD", "-","$RaceId.Kaiji", "-","$RaceId.Nichiji", "-","$RaceId.RaceNum" ] } } }]
);
bulk.execute();
一括登録または更新(upsert)
一括削除(remove)
インデックス
作成
- 1:昇順、-1:降順
db.collection.createIndex(
{ key1:1, key2:-1, ・・・},
{ <インデックスオプション>}
)
インデックスオプション
| 項目 | 説明 | 備考 |
|---|---|---|
| background | バックグラウンド実行 | データ大量時、アプリケーションへの応答遅延防止など |
| name | インデックス名を指定 | |
| unique | ユニークインデックス | null不可 |
| partialFilterExpression | フィルタを作成し一致したドキュメントの部分インデックスを作成 | 以下を指定できる
|
インデックス種類
| 種類 | 説明 | 備考 |
|---|---|---|
| デフォルトインデックス | _idフィールドに作成される | 削除できない |
| テキストインデックス | 文字列コンテンツに対するテキスト検索クエリをサポートするテキストインデックスを作成 | 作成には、keyに"text"を指定する
db.collection.createIndex({ key: "text" })
|
| TTLインデックス | 特定の時間または時刻にドキュメントを自動削除するために利用する | Date型、Date型を含む配列、expireAfterSecondsが経過したドキュメントを自動で削除する
db.collection.createIndex({
{key: 1},
{expireAfterSeconds:<秒数>}
})
|
| ハッシュインデックス | フィールド値のハッシュをインデックスにする | ランダム分布をも持つが、値一致飲みサポート |
| 地理的インデックス | プレーンジオメトリ、球面ジオメトリ |
確認
db.collection.getIndexes()
削除
- 上記で確認した、nameを指定する
db.collection.dropIndex("インデックス名")
再構築
db.collection.reIndex()
Tips
stringをintに変換
db.getCollection('O1').find({},{tosu:{ '$toInt': '$TorokuTosu' }})
プログラミング
C#
Insert
using MongoDB.Driver;
:
var client = new MongoClient("mongodb://puli-mon.local");
var mongoDb = client.GetDatabase("jra");
var colH1 = mongoDb.GetCollection<JV_H1_HYOSU_ZENKAKE>("h1");
:
colH1.InsertOne(rec);
© 2006 矢木浩人