Skip to content

Instantly share code, notes, and snippets.

@kanonji
Last active June 23, 2018 13:22
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kanonji/5903565 to your computer and use it in GitHub Desktop.
Save kanonji/5903565 to your computer and use it in GitHub Desktop.
最近mongodbを使っていてのメモ

アトミックな操作

値が変更されていなかったら更新

Compare and Swap

https://wiki.10gen.com/pages/viewpage.action?pageId=7209573

ロック

MongoDB 2.2以前はReaders-Writerロックなので、長いクエリーが走ったその瞬間から、短いクエリーもロックされる。 http://d.hatena.ne.jp/hiroppon/20130520/1369017430

2.2で、ロックによる改善は、ロック競合を減らすことにより、ライト時のスループットに本質的な便益を提供しています。David Mytton氏がこの主題で良い記事を書き上げました。MongoDBの2.4は、2.0と2.2で提供した改善を超えて、ロックの粒度に関して何も追加していません。私たちは、2.6では、ドキュメントレベルのロックを検討しています。改善を生み出したロックは、充分本質的だったので、コレクション・レベルのロックは大きな改善を追加しないでしょう。なので、ドキュメントレベルのロックが、次のステップでしょう。 http://www.infoq.com/jp/news/2013/04/mongodb-2-4

ロックの粒度がv2.0までのGlobalロック(Mongodインスタンス全体のロック)からDBレベルロックとなり,並列処理がより効率よく行えるようになりました。複数のDBで運用しているシステムには恩恵がありますが,それほど対象ユーザは多くはないかもしれません。

次のステップであるCollectionレベルロックでは多くのユーザに恩恵があると思われますが,実装は次バージョン以降となります。JIRAにチケット登録されており,2012年11月末現在でFix Version/s: Planning Bucket Aとなっており実装バージョンは未定となってます。 http://gihyo.jp/dev/serial/01/mongodb/0002

結局コレクションロックは実装されなかった。2.6でドキュメントロックが導入されるかもしれない。が、現状はDBレベルのロック

参考

データ型一覧

Type Name 			Type Number
Double				1
String				2
Object 				3
Array 				4
Binary data 			5
Object id 			7
Boolean 			8
Date 				9
Null 				10
Regular expression 		11
JavaScript code 		13
Symbol 				14
JavaScript code with scope 	15
32-bit integer 			16
Timestamp 			17
64-bit integer 			18
Min key 			255
Max key 			127 

http://shoken.hatenablog.com/entry/20120411/p1

http://jp.docs.mongodb.org/manual/reference/operator/type/

殆ど翻訳されてないけど日本語ドキュメントのURL

http://jp.docs.mongodb.org/manual/

空のコレクションを作成する

db.createCollection('name')

http://docs.mongodb.org/manual/reference/method/db.createCollection/

日付文字列と比較

日付文字列に対して$gte, $lteが機能しているように見える。 Mongoがほんとに日付として処理してるのかは知らない。

年-月-日

db.things.insert({"date": "2013-01-01"});
db.things.insert({"date": "2013-01-02"});
db.things.insert({"date": "2013-01-03"});
db.things.insert({"date": "2013-01-04"});
db.things.insert({"date": "2013-01-05"});
db.things.find({"date": {"$gte": "2013-01-04"}})
//{"date": "2013-01-04"}
//{"date": "2013-01-05"}
db.things.find({"date": {"$gte": "2013-01-02", "$lte": "2013-01-04"}})
//{"date": "2013-01-02"}
//{"date": "2013-01-03"}
//{"date": "2013-01-04"}
db.things.find({"date": {"$gt": "2013-01-02", "$lt": "2013-01-04"}})
//{"date": "2013-01-03"}

年-月

db.things.insert({"date": "2013-01"});
db.things.insert({"date": "2013-02"});
db.things.insert({"date": "2013-03"});
db.things.insert({"date": "2013-04"});
db.things.insert({"date": "2013-05"});
db.things.find({"date": {"$gte": "2013-04"}})
//{"date": "2013-04"}
//{"date": "2013-05"}
db.things.find({"date": {"$gte": "2013-02", "$lte": "2013-04"}})
//{"date": "2013-02"}
//{"date": "2013-03"}
//{"date": "2013-04"}
db.things.find({"date": {"$gte": "2013-02-02", "$lte": "2013-04-22"}})
//{"date": "2013-03"}
//{"date": "2013-04"}
db.things.find({"date": {"$gte": "2013-02-00", "$lte": "2013-04-22"}})
//{"date": "2013-03"}
//{"date": "2013-04"}

YYYY-mm-dd HH:mm:ss

db.things.insert({"date": "2013-01-01 13:13:13"});
db.things.insert({"date": "2013-01-02 13:13:13"});
db.things.insert({"date": "2013-01-03 13:13:13"});
db.things.insert({"date": "2013-01-04 13:13:13"});
db.things.find({"date": {"$gte": "2013-01-02", "$lte": "2013-01-03"}})
//{"date": "2013-01-02 13:13:13"}

時分秒がはいるので$gte, $lteでもイコールにならない。

db.things.insert({"date": "2013-01-01 00:00:00"});
db.things.insert({"date": "2013-01-01 13:13:13"});
db.things.insert({"date": "2013-01-01"});
db.things.insert({"date": "2013-01-02 13:13:13"});
db.things.find({"date": {"$gt": "2013-01-01", "$lt": "2013-01-02"}})
//{"date": "2013-01-01 00:00:00"}
//{"date": "2013-01-01 13:13:13"}
db.things.find({"date": {"$gte": "2013-01-01", "$lt": "2013-01-02"}})
//{"date": "2013-01-01 00:00:00"}
//{"date": "2013-01-01 13:13:13"}
//{"date": "2013-01-01"}

{"$gt": "2013-01-01"}{"date": "2013-01-01"}を含まないが{"date": "2013-01-01 00:00:00"}を含む

ISODate()

> ISODate
function (isoDateStr) {
    if (!isoDateStr) {
        return new Date;
    }
    var isoDateRegex = /(\d{4})-?(\d{2})-?(\d{2})([T ](\d{2})(:?(\d{2})(:?(\d{2}(\.\d+)?))?)?(Z|([+-])(\d{2}):?(\d{2})?)?)?/;
    var res = isoDateRegex.exec(isoDateStr);
    if (!res) {
        throw "invalid ISO date";
    }
    var year = parseInt(res[1], 10) || 1970;
    var month = (parseInt(res[2], 10) || 1) - 1;
    var date = parseInt(res[3], 10) || 0;
    var hour = parseInt(res[5], 10) || 0;
    var min = parseInt(res[7], 10) || 0;
    var sec = parseFloat(res[9]) || 0;
    var ms = Math.round(sec % 1 * 1000);
    sec -= ms / 1000;
    var time = Date.UTC(year, month, date, hour, min, sec, ms);
    if (res[11] && res[11] != "Z") {
        var ofs = 0;
        ofs += (parseInt(res[13], 10) || 0) * 60 * 60 * 1000;
        ofs += (parseInt(res[14], 10) || 0) * 60 * 1000;
        if (res[12] == "+") {
            ofs *= -1;
        }
        time += ofs;
    }
    return new Date(time);
}
> d.format('YYYY-MM-DD HH:mm:ssZ')
2013-08-02 20:44:01+09:00
> d.format('YYYY-MM-DD HH:mm:ss')
2013-08-02 20:44:01
> ISODate(d.format('YYYY-MM-DD HH:mm:ssZ'))
ISODate("2013-08-02T11:44:01Z")
> ISODate(d.format('YYYY-MM-DD HH:mm:ss'))
ISODate("2013-08-02T20:44:01Z")

タイムゾーンを指定すれば、考慮したUTCになる。

WHERE IN

db.collection.find( { _id : { $in : [1,2,3,4] } } );
db.collection.find( { name : { $in : ['foo','bar'] } } );

$inオペレータをつかう。

http://docs.mongodb.org/manual/reference/operator/#comparison 他にもいろんなオペレータがある。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment