2013年7月6日土曜日

MongoDBの基礎

MongoDB

ドキュメント指向データベース NoSQL

パフォーマンス良い、スケーラブル良い→大量のデータを扱う

ドキュメント指向

カラムが固定されない=スキーマレス
 ユーザ、状況、データによって柔軟に変更可能

以下のような用語を使用する。()はRDBMSの用語

コレクション (Table)

ドキュメント (Record)

データ格納はJSON


ex)
[x, y, z] ←ただ値を格納したいとき
{"key":value, "key":value} ←keyとvalueの組で格納するとき 
{"key":value, "key":[x,y,z]} ←多重配列的に格納するとき

on Windows

Windowsでは、公式サイトからmongodbのバイナリzipを取得、解凍して、任意のディレクトリに
置いた後、以下のコマンドでdataを保存するディレクトリを指定してから使う。


> mongod --dbpath C:\mongodata\db\data

接続

> mongod

シェルでは JavaScript が使える。


データベース

show dbs:一覧表示

use [データベース名]:新しいデータベースの作成(これだけだとempty状態)

db.createCollection("コレクション名"):新しいコレクションを作成する

db.stats():一覧表示

db.dropDatabase();:データベースの削除


コレクション


db.createCollection("dictionary"); :dictionaryコレクション作成

db.createCollection("points"); :pointsコレクション作成

show collections :コレクションの一覧を見る

コレクションを操作したいときは、dbのあとの要素に操作したコレクションを「.」で結合する

db.points.drop(); :pointsコレクションを削除する

db.dictionary.renameCollection("textdic"); :deictionary コレクションの名前を textdic に変更


ドキュメント

mongodb textdic :textdicデータベースに接続

show collections :コレクションの一覧を見る

db.points.insert({["date":"vector", "word":"test1"}); :pointsコレクションにdate:vector、word:test1の要素をもつドキュメントを追加

スキーマレスなので、同じコレクションに大して、構造のドキュメントを追加する必要がない。

db.points.insert({"date":"vector","wordarray":["test2", "test3"]}); :pointsコレクションに上記とは違う構造のドキュメントを追加

db.points.find() :pointsコレクション内のドキュメント一覧

db.points.remove():pointsコレクション内のドキュメントを削除


大量のドキュメントの生成

JavaScriptが使える利点を使って、データを生成する。

ex)pointsコレクションにランダムな点データドキュメントをmod3でグループに分けて10点生成する。

> for (var i=0; i<10; i++) {
... db.points.insert(
... {"pointnum":i,
... "group":i % 3,
... "x":Math.floor(Math.random()*100),
... "y":Math.floor(Math.random()*100)
... }
... );
... }
結果を見る。

db.points.find()
{ "_id" : ObjectId("51d77bfe3e6506f15ba6aa12"), "pointnum" : 0, "group" : 0, "x : 5, "y" : 8 }
{ "_id" : ObjectId("51d77bfe3e6506f15ba6aa13"), "pointnum" : 1, "group" : 1, "x : 54, "y" : 45 }
{ "_id" : ObjectId("51d77bfe3e6506f15ba6aa14"), "pointnum" : 2, "group" : 2, "x : 47, "y" : 9 }
{ "_id" : ObjectId("51d77bfe3e6506f15ba6aa15"), "pointnum" : 3, "group" : 0, "x : 16, "y" : 31 }
{ "_id" : ObjectId("51d77bfe3e6506f15ba6aa16"), "pointnum" : 4, "group" : 1, "x : 84, "y" : 28 }
{ "_id" : ObjectId("51d77bfe3e6506f15ba6aa17"), "pointnum" : 5, "group" : 2, "x : 35, "y" : 71 }
{ "_id" : ObjectId("51d77bfe3e6506f15ba6aa18"), "pointnum" : 6, "group" : 0, "x : 8, "y" : 90 }
{ "_id" : ObjectId("51d77bfe3e6506f15ba6aa19"), "pointnum" : 7, "group" : 1, "x : 13, "y" : 53 }
{ "_id" : ObjectId("51d77bfe3e6506f15ba6aa1a"), "pointnum" : 8, "group" : 2, "x : 21, "y" : 11 }
{ "_id" : ObjectId("51d77bfe3e6506f15ba6aa1b"), "pointnum" : 9, "group" : 0, "x : 10, "y" : 63 }

ドキュメントの抽出

db.points.find():全件抽出
db.points.find({"group":0});:groupが0のもののみ抽出
db.points.find({"group":0}, {"pointnum":true});:gourpが0のものの、pointnumのみ抽出
db.points.find({"group":{$ne:0}}); :groupが0で無いもののみ抽出 $ne→not equals
db.points.find({"x":{$gt:5}});:xが5より大きい
db.points.find({"x":{$gte:5}});:xが5以上
db.points.find({"x":{$lt:5}});:xが5より小さい
db.points.find({"x":{$lte:5}});:xが5以下
db.points.find({"x":{$gt:5, $lt:30}});:xが5より大きく30より小さい

正規表現

db.points.find({"":{$regrex:/<正規表現パターン>/i}});:正規表現パターンに合致したものを抽出

ソート

db.points.find().sort({"score":1}); :scoreで昇順に取得、-1だと降順


件数制限

db.points.findOne(); :先頭から1件抽出
db.points.find().limit(3); :先頭から3件抽出
db.points.find().skip(2).limit(3); :添字2 (0開始) のドキュメントから3件抽出
db.points.find().count(); :抽出した件数


ユニークな値を取得

db.points.distinct("group"); :ユニークな値を抽出

包含関係

db.points.find({"group":{$in:[0 ,1]}}); :グループが0または1に含まれるものを抽出
db.points.find({"group":{$nin:[0 ,1]}}); :グループ0か1以外を抽出


存在

db.points.find({"group":{$exists:true}}); :groupが存在しているドキュメントのみ。

Index インデックス

> db.points.getIndexes(); 現在のインデックスを参照
[
        {
                "v" : 1,:
                "key" : {
                        "_id" : 1
                },
                "ns" : "textdic.points",
                "name" : "_id_"
        }
]
db.points.ensureIndex({"pointnum":1});:pointnumに昇順Indexはる、-1だと降順
db.points.ensureIndex({"pointnum":1}, {"unique":true}); :pointnumにuniqueな昇順Indexはる、
db.points.dropIndex({"pointnum":1}); :インデックスの削除

ドキュメントの更新

updateの引数:1つ目が抽出条件、2つ目が置き換えたい値

db.points.update({"pointnum": 2}, {$set:{"x": 2000}}); :pointnum2のドキュメントのxを2000に書き換える
db.points.update({"pointnum": 3}, {$inc:{"x": -10}}); :pointnum3のど球面とのxを-10する
db.points.update({"pointnum": 5}, {$unset:{"x":1}}); :pointnum5の要素xを削除する
db.points.update({"pointnum": 6}, {$rename:{"y":"z"}}); :pointnum6の要素のyの名前をzに変更

updateの引数:3つ目が「upsert」、あれば変更、なければinsert(3つ目をtrueにする)

db.points.update({"pointnum":"100"},{$inc:{"x":1000}}, true);

                                                     
updateの引数4つ目が「date更新件数」:4つ目がtrueだと全件に適用

db.points.update({}, {$inc:{"y": 3000}}); :最初の1件のみ
db.points.update({}, {$inc:{"y": 3000}}, false, true);

外部ファイルからコマンドを実行

方法1

コマンド を記述したファイルを用意。(JavaScriptなので拡張子はjsとする)

mongo [データベース名] [実行したいjsファイル]


方法2

mongoインタラクティブコマンドから実行

mongo [データベース名]で接続したら

load("[実行したいjsファイル名(windowsでは\を\\とすることに注意)]");

バックアップと復元

ダンプ

mongodump:バックアップを取得

コマンドの出力にバックアップバイナリファイルの出力先が出る。

mongodump --db textdic:

C:\Users\真宏>mongodump --db textdic
connected to: 127.0.0.1
Sat Jul 06 12:38:25.349 DATABASE: textdic        to     dump\textdic
Sat Jul 06 12:38:25.351         textdic.system.indexes to dump\textdic\system.in
dexes.bson
Sat Jul 06 12:38:25.353                  2 objects
Sat Jul 06 12:38:25.355         textdic.dictionary to dump\textdic\dictionary.bs
on
Sat Jul 06 12:38:25.357                  0 objects
Sat Jul 06 12:38:25.357         Metadata for textdic.dictionary to dump\textdic\
dictionary.metadata.json
Sat Jul 06 12:38:25.361         textdic.points to dump\textdic\points.bson
Sat Jul 06 12:38:25.361                  10 objects
Sat Jul 06 12:38:25.363         Metadata for textdic.points to dump\textdic\poin
ts.metadata.json

リストア

mongorestore --drop [dumpファイルの格納ディレクトリ]:元のデータをdropして、dumpから復元する



便利だが、はやく Json に慣れたい。

0 件のコメント:

コメントを投稿