#contents
* MongoDBの位置づけ [#s571d1fe]
||種別|製品例|利用シーン|h
|SQL |RDB |Oracle, PostgreSQL, MySQL |一般業務 (トランザクション処理)|
|NoSQL|KVS (Key-Value Store)|Memcached, Redis |キャッシュ|
|~|ドキュメント指向DB |MongoDB, CouchDB, Elasticsearch |不定形なJSONがたくさんあるんでうまいこと管理してほしい|
|~|列指向DB |Cassandra, HBase |Big Data の分析 (たくさんの属性をもつデータのあつまりから、ある属性(=ある列)だけを横断的にとってくる)|
-NoSQLが出はじめのころは、RDBを置き換えようという勢いだったけど、最近 (2019) は、RDB の補完の位置づけ
--RDB+KVS で、マスターデータを KVS でキャッシュするとかよくやられる
--HBase は、ガチの BigData 分析で使う
-ドキュメント指向DBは、良くも悪くも不定形なJSONのストレージですわな
--多種・大量のログをとにかくぶち込む (Elasticsearch)
--将来のデータ構造の変更を前提に、とりあえずお気軽にアプリを作ってみる (CouchDB = カウチDB)
--そこそこの量の不定形データをRDBっぽく使いたい (MongoDB = humongous db ばかでかい)
-ここでは、自分が機械学習に使うデータを MongoDB で管理することにする
--CSV や Excel で管理するには大きすぎるデータセット
--でも、がっつり HBase を組むほどではない
* RDB vs MongoDB [#h8c8384d]
-MongoDB のデータ構造の概念は、RDB と似ている
|RDB |MongoDB |h
|database |database |
|table |collection |
|row |document |
|column |field |
|index |index |
|primary key |_id field(*)|
_id field は、document ごとに勝手に採番される
-RDB
#ref(er.png)
--データは、テーブルに漏れなく・ダブりなく配置される
--テーブル(table) に格納されている 行(row) 同士の関係 (relation) によって、データを表す
-MongoDB
#ref(doc.png)
--データは、コレクションに重複して格納される
--ドキュメント (document) には、必要な情報がすべて格納され、ドキュメント同士は関係しない
-MongoDB には、トランザクションがない
*インストール [#n02d98eb]
Linux (Debian) の場合
$ sudo apt install mongodb
$ sudo systemctrl start mongodb
*Mongo Shell の練習 [#ubb38337]
-教科書
--The Little MongoDB Book, https://www.openmymind.net/2011/3/28/The-Little-MongoDB-Book/
--MongoDBの薄い本(日本語訳), https://www.cuspy.org/diary/2012-04-17/
-Database を作る
$ /usr/bin/mongo
MongoDB shell version: 3.2.11
connecting to: test
Welcome to the MongoDB shell.
> use learn
switched to db learn
> show dbs
learn 0.000GB
local 0.000GB
-Database を削除する
> use learn
> db.dropDatabase();
-Collection と Document を作成する
> db.getCollectionNames()
[ ]
> db.unicorns.insert({name: 'Aurora', gender: 'f', weight: 450})
WriteResult({ "nInserted" : 1 })
> db.getCollectionNames()
[ "unicorns" ]
-Document の削除
> db.unicorns.remove({})
WriteResult({ "nRemoved" : 2 })
-練習用のオブジェクトの導入
> db.load('unicorns.js');
true
unicorns.jsはこんな感じ
#code(javascript){{{
db.unicorns.insert({
name: "Horny",
dob: new Date(1992, 2, 13, 7, 47),
loves: ["carrot", "papaya"],
weight: 600,
gender: "m",
vampires: 63
});
db.unicorns.insert({
name: "Aurora",
dob: new Date(1991, 0, 24, 13, 0),
loves: ["carrot", "grape"],
weight: 450,
gender: "f",
vampires: 43
});
db.unicorns.insert({
name: "Unicrom",
dob: new Date(1973, 1, 9, 22, 10),
loves: ["energon", "redbull"],
weight: 984,
gender: "m",
vampires: 182
});
db.unicorns.insert({
name: "Roooooodles",
dob: new Date(1979, 7, 18, 18, 44),
loves: ["apple"],
weight: 575,
gender: "m",
vampires: 99
});
db.unicorns.insert({
name: "Solnara",
dob: new Date(1985, 6, 4, 2, 1),
loves: ["apple", "carrot", "chocolate"],
weight: 550,
gender: "f",
vampires: 80
});
db.unicorns.insert({
name: "Ayna",
dob: new Date(1998, 2, 7, 8, 30),
loves: ["strawberry", "lemon"],
weight: 733,
gender: "f",
vampires: 40
});
db.unicorns.insert({
name: "Kenny",
dob: new Date(1997, 6, 1, 10, 42),
loves: ["grape", "lemon"],
weight: 690,
gender: "m",
vampires: 39
});
db.unicorns.insert({
name: "Raleigh",
dob: new Date(2005, 4, 3, 0, 57),
loves: ["apple", "sugar"],
weight: 421,
gender: "m",
vampires: 2
});
db.unicorns.insert({
name: "Leia",
dob: new Date(2001, 9, 8, 14, 53),
loves: ["apple", "watermelon"],
weight: 601,
gender: "f",
vampires: 33
});
db.unicorns.insert({
name: "Pilot",
dob: new Date(1997, 2, 1, 5, 3),
loves: ["apple", "watermelon"],
weight: 650,
gender: "m",
vampires: 54
});
db.unicorns.insert({
name: "Nimue",
dob: new Date(1999, 11, 20, 16, 15),
loves: ["grape", "carrot"],
weight: 540,
gender: "f"
});
db.unicorns.insert({
name: "Dunx",
dob: new Date(1976, 6, 18, 18, 18),
loves: ["grape", "watermelon"],
weight: 704,
gender: "m",
vampires: 165
});
}}}
*検索 [#we8b778f]
-https://docs.mongodb.com/manual/reference/operator/query/#query-selectors
--compare
|$eq |equal|
|$ne |not equal|
|$gt |greater than|
|$gte|greater than equal|
|$lt |less than|
|$lte|less than equal|
--array
|$in |in|
|$nin|not in|
--logic
|$and|and|
|$not|not|
|$nor|not or|
|$or |or|
--element
|$exists |Do this element exist?|
-実行例
--オスかつ体重700kg以上
> db.unicorns.find({gender: 'm', weight: {$gt: 700}});
{ "_id" : ObjectId("5e0de0f41bf1dc20dedb5de0"), "name" : "Unicrom", "dob" : ISODate("1973-02-09T13:10:00Z"), "loves" : ["energon", "redbull" ], "weight" : 984, "gender" : "m", "vampires" : 182 }
{ "_id" : ObjectId("5e0de0f41bf1dc20dedb5de9"), "name" : "Dunx", "dob" : ISODate("1976-07-18T09:18:00Z"), "loves" : ["grape", "watermelon" ], "weight" : 704, "gender" : "m", "vampires" : 165 }
--オスまたは体重700kg以上
> db.unicorns.find({$or : [{gender: 'm'}, {weight: {$gt: 700}}]});
{ "_id" : ObjectId("5e0de0f41bf1dc20dedb5dde"), "name" : "Horny", "dob" : ISODate("1992-03-12T22:47:00Z"), "loves" : ["carrot", "papaya" ], "weight" : 600, "gender" : "m", "vampires" : 63 }
{ "_id" : ObjectId("5e0de0f41bf1dc20dedb5de0"), "name" : "Unicrom", "dob" : ISODate("1973-02-09T13:10:00Z"), "loves" : ["energon", "redbull" ], "weight" : 984, "gender" : "m", "vampires" : 182 }
{ "_id" : ObjectId("5e0de0f41bf1dc20dedb5de1"), "name" : "Roooooodles", "dob" : ISODate("1979-08-18T09:44:00Z"), "loves": [ "apple" ], "weight" : 575, "gender" : "m", "vampires" : 99 }
{ "_id" : ObjectId("5e0de0f41bf1dc20dedb5de3"), "name" : "Ayna", "dob" : ISODate("1998-03-06T23:30:00Z"), "loves" : ["strawberry", "lemon" ], "weight" : 733, "gender" : "f", "vampires" : 40 }
{ "_id" : ObjectId("5e0de0f41bf1dc20dedb5de4"), "name" : "Kenny", "dob" : ISODate("1997-07-01T01:42:00Z"), "loves" : ["grape", "lemon" ], "weight" : 690, "gender" : "m", "vampires" : 39 }
{ "_id" : ObjectId("5e0de0f41bf1dc20dedb5de5"), "name" : "Raleigh", "dob" : ISODate("2005-05-02T15:57:00Z"), "loves" : ["apple", "sugar" ], "weight" : 421, "gender" : "m", "vampires" : 2 }
{ "_id" : ObjectId("5e0de0f41bf1dc20dedb5de7"), "name" : "Pilot", "dob" : ISODate("1997-02-28T20:03:00Z"), "loves" : ["apple", "watermelon" ], "weight" : 650, "gender" : "m", "vampires" : 54 }
{ "_id" : ObjectId("5e0de0f41bf1dc20dedb5de9"), "name" : "Dunx", "dob" : ISODate("1976-07-18T09:18:00Z"), "loves" : ["grape", "watermelon" ], "weight" : 704, "gender" : "m", "vampires" : 165 }
--apple か grap が好き
> db.unicorns.find({"loves" : { $in : ["apple", "grape"] }}, {"_id":0, "name":1, "loves":1, "gender":1})
{ "name" : "Aurora", "loves" : [ "carrot", "grape" ], "gender" : "f" }
{ "name" : "Roooooodles", "loves" : [ "apple" ], "gender" : "m" }
{ "name" : "Solnara", "loves" : [ "apple", "carrot", "chocolate" ], "gender" : "f" }
{ "name" : "Kenny", "loves" : [ "grape", "lemon" ], "gender" : "m" }
{ "name" : "Raleigh", "loves" : [ "apple", "sugar" ], "gender" : "m" }
{ "name" : "Leia", "loves" : [ "apple", "watermelon" ], "gender" : "f" }
{ "name" : "Pilot", "loves" : [ "apple", "watermelon" ], "gender" : "m" }
{ "name" : "Nimue", "loves" : [ "grape", "carrot" ], "gender" : "f" }
{ "name" : "Dunx", "loves" : [ "grape", "watermelon" ], "gender" : "m" }
表示項目の制御は、第二引数にJSONで記述する。表示したい項目に1を設定する。_idだけはデフォルトで1なので、表示したくない場合には明示的に0を指定する必要がある
--整形して出力
> db.unicorns.find({"loves" : { $in : ["apple", "grape"] }}, {"_id":0, "name":1, "loves":1, "gender":1}).pretty()
--項目が存在する
> db.unicorns.find({vampires: {$exists: false}})
{ "_id" : ObjectId("5e0de0f41bf1dc20dedb5de8"), "name" : "Nimue", "dob" : ISODate("1999-12-20T07:15:00Z"), "loves" : ["grape", "carrot" ], "weight" : 540, "gender" : "f" }
なんか、血を吸わないのは Nimue だけみたい
--_id指定で検索する場合
> db.unicorns.find({_id: ObjectId("5e0de0f41bf1dc20dedb5de1")})
{ "_id" : ObjectId("5e0de0f41bf1dc20dedb5de1"), "name" : "Roooooodles", "dob" : ISODate("1979-08-18T09:44:00Z"), "loves": [ "apple" ], "weight" : 575, "gender" : "m", "vampires" : 99 }
----
[[Deep Learning]]