View
14
Download
2
Embed Size (px)
DESCRIPTION
MongoDB 勉強会
Citation preview
MongoDB
10.7.07
株式会社あくしゅ三上 悟
Agenda
• Introduction MongoDB• CRUD• Index• Geospatial• MongoMapper
MongoDBStable 1.4.4
Devlopment 1.5.4
• humongouss(huge + monstrous) 超でかい• Document Database• C++• Open Source• GNU AGPL v3.0 Licence• OSX,Linux,Windows,Solaris |32bit,64bit• Development and Support:10 gen
MongoDB vs CouchDBMongoDBRDBMS,KeyValuc,DocumentDatabase のいいとこどりのデータベースなんでもできる。REST ではなく、独自プロトコルを利用しているので早い
CouchDBCouchDB も同じドキュメントデータベースJSON 、 Map/Reduce, スキーマレス N-Master Replication 似ているCouchDB は用意している中で扱うには楽できるらしい。 Relax 。詳しくは知らない。
http://www.mongodb.org/display/DOCS/Comparing+Mongo+DB+and+Couch+DB
MongoDB In Production
その他いっぱい日本のサービスは掲載されていない。
Use Cases
• 債券など非常に重要な取引では使わない。 RDBMS とのハイブリッド型にする
• 非常に高い更新が発生する問題に向いている。例えば頻繁な更新されるウェブサイトリアルタイム解析カウンタソーシャルゲーム等
Licencemongod と mongos は GNU AGPL v3.0 LicenceGPLv3 は組み込まれて、配布されるときに、著作権が適用される。今日、クラウドのようにネットワーク経由で利用する場合がほとんどのため、この抜け穴をつぶすために作られたライセンス。GPLv3 との違いはネットワーク経由で利用した場合でも適用される。データベースを改変したら、データベースのコードの公開が必要。ちゃんとコミュニティーに貢献してね。
では自分のアプリケーションに組み込んだ場合はコードを公開する必要があるか?
Driver は Apache License v2.0 のため、自社のウェブアプリケーションに組み込んで利用しても、アプリケーションのソースコードの公開義務はない。また社内で利用するアプリケーションの場合には、データベースに改変を加えてもソースコードの公開義務はない。
http://www.mongodb.org/display/DOCS/Licensing
System
• Document-oriented storage• Full Index Support• Replication & High Availability• Auto-Sharding• Querying• Fast In-Place Updates• Map/Reduce• GridFS
Collections
• RDB のテーブルにあたるもの• BSON Documents Group
Documents
• RDB のレコードにあたるもの• スキーマレス• Key/Value(BSON)• ユニークな ObjectID が付与
Field
• RDB のカラムにあたるもの• KeyValueStore のキーにあたるもの
ObjectID
• BSON Object Data Type• Document ID: _id• Unique• Index Primary Key• 16 進数文字列 ObjectId( "47cc67093475061e3d95369d" )
http://www.mongodb.org/display/DOCSJP/Object+ID
ObjectID
• ObjectID の仕様 12バイト• 4byte timestamps (big endian)• 3byte machine• 2byte process id• 3byte counter (big endian)
0 1 2 3 4 5 6 7 8 9 10
11
time machine pid increment
BSON(Binaly JSON)
• Document に格納するデータ• JSON ベース• バイナリ
BSON DataType
• String• Integer• Double• Date• Byte array(binary data)• Boolean(true and false)• Null• BSON object
Start/Stop MongoDB
#Start mongo daemon./bin/mongod \--dbpath /var/lib/mongodb/ \--port 27017 &
#Stop mongo daemonkill -2 PIDOR
kill -15 PID
MongoDB Shell
./bin/mongo
MongoDB shell>use mydb
Before StartMongoDB ではあらかじめデータベースを作る必要はありません。何かデータを作成すると、基本的なコレクションとデータベースを作成します。存在しないコレクションに対してクエリーを発行すると、 MongoDB は空のコレクションとして返します。 use コマンドでデータベースを切り替えても、データベースはすぐには作成されません。データベースは、最初にデータが作成されたときに作成されます。
チュートリアルよりhttp://www.mongodb.org/pages/viewpage.action?pageId=5079135
CRUD
CREATE
SQLINSERT INTO db.mycollections(name) VALUES(“mongo”);
Dynamic Querysdb.mycollections.save({ name : “mongo”});
http://www.mongodb.org/display/DOCS/Inserting
READ
SQLSELECT * FROM mycolletions
Dynamic Querysdb.mycollections.find();
READORDER BY & LIMIT/OFFSET
SQLSELECT * FROM db.mycollections
WHERE name = “mongo” ORDER BY id DESC LIMIT 1,10;
Dynamic Querysdb.mycollections.find({name:”mongo”}).sort({id: -1}).skip(1).limit(10);
http://www.mongodb.org/display/DOCS/Querying
Conditional Operators• $gt,$lt,$gte,$lte• $ne• $in• $nin• $mod• $all• $size• $exists• $type• $elemMatch• $not• $where
http://www.mongodb.org/display/DOCS/Advanced+Queries
Conditional Operators
SQL Conditions MongoDB Operators
key > value key:{$gt:value}
key < value key:{$lt:value}
key >= value key:{$gte:value}
key <= value key:{$lte:value}
key <> value key:{$ne:value}
key IN(value) key:{$in:[value]}
key NOT IN(value) key:{$nin:[value]}
key EXIST(value) key:{$exist:value}
SQL Conditions MongoDB Oprators
key = value key:value
WHERE key = value .find({key:value})
.find({key:{Operator:value})WHERE key Condtion value
SELECTbetween
SQLSELECT * FROM logs
where created_at BETWEEN ‘2010-06-10’ AND ‘2010-06-12’
Dynamic Querysdb.logs.find({
created_at:{$gte:new Date(2010,6,10)},created_at:{$lte:new Date(2010,6,12)}
});
もしくは
db.logs.find({$where:"this.created_at >= new Date(2010,6,10) && this.created_at <= new Date(2010,6,12)"
})
READCOUNT
SQLSELECT COUNT(*) FROM users;
Dynamic Querysdb.users.count();
READDISTINCT
SQLSELECT DISTINCT(name) FROM users;
Dynamic Querysdb.users.distinct(“name”);
READGROUP BY
SQLSELECT name,sum(marks) FROM users
WHERE name=“mikami” GROUP BY name;
Dynamic Querysdb.users.group({
key:{name:true},cond:{name:"mikami"},reduce: function(obj,prev){prev.msum += obj.marks},initial: {msum:0}
});
組み込みの Map/Reduce を使う
UPDATEdb.collection.update( Criteria, ObjNew, Upsert, Multi )
Criteriaアップデートするレコードを選択するためのクエリー
ObjNew対象のオブジェクトを、アップデートするオブジェクト、または $ オペレータ ($in
c など )
Upsertレコードが存在しない場合にインサートするかどうか
Multicriteria にマッチするオブジェクトすべてをアップデートするかどうか ( デフォルトでは最初に見つかったオブジェクトのみがアップデートされる )
http://www.mongodb.org/pages/viewpage.action?pageId=7209549
Modifier Operations
• $inc• $set• $unset• $push• $pushAll• $addToSet• $pop• $pull• $pullAll
http://www.mongodb.org/display/DOCS/Updating
$incインクリメント/デクリメント or シーケンシャルナンバー
SQLupdate entries set count= count+1 where _id =
'4c2bf9d691951da31517df10’
DynamicQuerysdb.entries.update(
{_id:ObjectId('4c2bf9d691951da31517df10')},{$inc:{count:1}}
)
$setフィールド更新
SQLupdate entries set name = ”ruby" where user_id = 1
DynamicQuerysdb.entries.update({user_id:1},{$set:{name:”ruby“}})
※value には配列やオブジェクトも格納できるため、まるごと値が置き換わる
$unsetフィールド削除
SQLALTER TABLE entries DROP COLUMN name;※すべて削除のみ
DynamicQuerysdb.entries.update(
{_id:ObjectId('4c2bf9d691951da31517df10')},{$unset:{name:1}}
)※特定のドキュメントのフィールドだけ消すことができる
$push
SQLALTER TABLE entries ADD (body varchar(255))UPDATE entries SET tag="MongoDB" where _id = 'c2bfaea91951da31517df12'’
DynamicQuerysdb.entries.update(
{_id:ObjectId('4c2bfaea91951da31517df12')},{$push:{tag:"MongoDB"}}
)
tag に配列でプッシュされる。tag = ['MongoDB'] 2回目tag = ['MongoDB','MongoDB']
$pushAll
DynamicQuerysdb.entries.update(
{_id:ObjectId('4c2bfa4c91951da31517df11')},{$push:{tag:["Ruby","Rails","MongoDB"]}}
)
まとめて格納できる。tag = [['Ruby','Rails','MongoDB']]
$addToSet
DynamicQuerysdb.entries.update(
{_id:ObjectId('4c2bfaea91951da31517df12')},{$addToSet:{tag:”MongoDB"}}
)
tag の配列にプッシュされる。値は重複しないtag = ['MongoDB'] 2回目tag = [‘MongoDB’]
$pop
DynamicQuerysdb.entries.update(
{_id:ObjectId('4c2bfaea91951da31517df12')},{$pop:{tag:1}}
)
{tag:1} の値は 1=pop -1=shift
$pull
DynamicQuerysdb.entries.update(
{_id:ObjectId('4c2bfaea91951da31517df12')},{$pull:{tag:"MongoDB"}}
)
tag で指定した値にマッチする値をすべて削除
$pullAll
DynamicQuerysdb.entries.update(
{_id:ObjectId('4c2bfaea91951da31517df12')},{$pullAll:{tag:["MongoDB","Ruby"]}}
)
tag で指定した配列の中に含まれる値にマッチする値をすべて削除
DELETE
SQLDELETE FROM db.mycollections WHERE id = 12345678900
Dynamic Querysdb.mycollections.remove({_id: myobject._id});
http://www.mongodb.org/display/DOCS/Removing
DELETE
SQLDELETE FROM users WHERE age < 30
Dynamic Querysdb.users.remove({age:{$lt:30}});
Server Side Javascript
JavascriptEngine(SpiderMonkey)v8 は開発中
ストアドプロシージャーいままで解説した関数は Javascript で定義されている()を外すと、中の実装が見れる。>db.test.findfunction (query, fields, limit, skip) { return new DBQuery(this._mongo, this._db, this, this._fullName,
this._massageObject(query), fields, limit, skip);}
中身のコードhttp://github.com/mongodb/mongo/tree/master/shell/
Server Side Javascript新しく定義することもできる。>db.system.js.save({_id: "sum", value: function (x, y) { return x + y; }});>db.eval("return sum(2, 3);");5
直接スクリプトを実行することも可能./bin/mongo example.js
最近、海外で流行っている node.js との相性がいいNode.jsv8 エンジンを組み込んだイベントドリブンな Web サーバー
Index
Index
RDBCREATE INDEX name ON mycollections(name);
MongoDBdb.mycollections.ensureIndex({name:1}); #ASCdb.mycollections.ensureIndex({name:-1}); #DESC
http://www.mongodb.org/pages/viewpage.action?pageId=5800049
Index
• B-Tree• 指定されたキーで高速に検索が可能• _id は常にインデックスが生成される• すべてのフィールドにインデックスを生成できる• フィールドに配列が保存された場合、 それぞれの要素にインデックスを作成する。
Multi Key Index
db.things.ensureIndex({j:1, name:-1});
Unique Index
db.things.ensureIndex({firstname: 1, lastname: 1}, {unique: true}
);
Geospatial
Geospatial
地理空間を扱うための、インデックス、クエリーがサポートされている。
Indexdb.map.ensureIndex({location: “2d”})
Query$near 現在地から近い位置情報を検索$box 長方形の範囲内の位置情報を検索$center 中心から半径の距離に含まれる位置情報を検索
Geospatial• まだ開発途中• Development 1.5.4 ( 2010/07/02 Releasae) で $box,$circle の
バグが解消された。
• 地球は丸いのに、平面で計算しているため、• 正確な位置情報を取得できない。
Foursqure の中の人いわく、近い距離 (1degree=110km)以内なら問題ない。Foursquare & MongoDB(http://bit.ly/cOsWa8)
( Javascript で計算すれば可能。 パフォーマンスは未調査)
Index
RDB(MySQL)INSERT INTO map(`latlng`)
VALUES(GeoFromText(POINT(35.68238, 139.7665));CREATE SPATIAL INDEX latlng ON map(latlng);
MongoDBdb.map.insert(location:
{lat:35.68238},{lng:139.7665}
);db.map.ensureIndex({location: “2d”})
$near
>db.places.find( { loc : { $near : [35,139] ,1} }).limit(10)
1degree以内の位置を取得する。
$center
> center = [50, 50] > radius = 10 > db.places.find(
{"loc" : {"$within" : {"$center" : [center,
radius]}}}
)
$box
>box = [[40, 40], [60, 60]] >db.places.find({"loc" :
{"$within" : {"$box" : box}}}
)
See also• Documenthttp://www.mongodb.org/display/DOCS/Developer+Zone
• Cookbookhttp://cookbook.mongodb.org/index.html
• Video & Slideshttp://www.mongodb.org/display/DOCS/Events
• Articles http://www.mongodb.org/display/DOCS/Articles
See also
• Slideshttp://www.slideshare.net/fuchaoqun/mongodb-in-action-2976022
MongoMapper
http://github.com/jnunemaker/mongomapper
MongoMapperStable 0.8.2
• MongoDB を ActiveRecord を扱うように 操作できる ruby のデータベースラッパー
MongoMapper vs Mongoid
Good• Support Rails2.3 is good• Plugin system• ActiveRecord• Building code (http://github.com/patcito/shapado)
Bad・ Master/Slave replication Clusters does not support.
See also:http://bit.ly/9diwYp
MongoMapper
ActiveRecordclass Person < ActiveRecord::Base end
MongoMapperclass Person
Include MongoMapper::Document end
gems
gem install mongo_mapper #the c extensions (for production) gem install mongo_ext
Setupconfig/enviroment.rb
config.gem 'mongo'config.gem 'mongo_mapper'
#remove ActiveRecord
config.frameworks -= [ :active_record, :active_resource ]
Schema Designclass Person include MongoMapper::Document
include MongoMapper::Document
key :first_name, String, :required => true key :last_name, String, :required => true key :age, Integer, :numeric => true key :born_at, Time key :active, Boolean key :fav_colors, Array
validates_presence_of :first_name validates_presence_of :last_name validates_numericality_of :age
End
Query
Dynamic Querysdb.collections.find(name:”mikami”);
Mongo Mapperself.query.where(:name => “mikami”).find
See also• http://blog.bitzesty.com/mongodb-with-mongomapper-and-ruby-on-rails