mongo shellの操作まとめ

More than 3 years have passed since last update.


Mongo shellの操作まとめ

下記の環境で動作確認を行いました。


  • Windows7 (64bit)

  • MongoDB 3.0.2

この記事の説明で使用するコレクション


  • データベース: test

  • コレクション名: product

Field
Data Type
Desc

no
no
品番

name
string
品名

price
int
価格

variety
array
(*)バラエティ

snack
boolean
食用油で揚げている菓子類

drink
boolean
清涼飲料水類

activate
boolean
true:取扱可、false:不可

update_dt
date
更新日

バラエティ配列の要素は下記のオブジェクト

Field
Data Type
Desc

flavor
string

ppl
int
人気度(3:大、2:中、1:小)

サンプルデータの準備

この後の説明で使用するデータを下記のように作成します。


sample_data

> use test

> db.product.insert([
{no:1, name:"うまい棒", price:10, variety:[{flavor:"メンタイ", ppl:3},{flavor:"サラミ", ppl:3},{flavor:"ピザ", ppl:2},{flavor:"オニオンサラダ", ppl:2},{flavor:"コーンポタージュ", ppl:1}], snack:true, activate:true, update_dt:ISODate("2015-01-01T00:00:00+09:00") },
{no:2, name:"ポテトフライ", price:30, variety:[{flavor:"ステーキ", ppl:2},{flavor:"フライドチキン", ppl:1},{flavor:"カルビ", ppl:2}], snack:true, activate:false, update_dt:ISODate("2015-01-15T00:00:00+09:00") },
{no:3, name:"きなこ棒", price:10, activate:true, update_dt:ISODate("2015-01-31T00:00:00+09:00")},
{no:4, name:"生いきビール", price:40, drink:true, activate:false, update_dt:ISODate("2015-02-01T00:00:00+09:00")},
{no:5, name:"フルーツヨーグル", price:20, activate:true, update_dt:ISODate("2015-02-15T00:00:00+09:00")},
{no:6, name:"コーヒー牛乳キャンディ", price:10, activate:true, update_dt:ISODate("2015-02-28T00:00:00+09:00")},
{no:7, name:"ミニコーラ", price:30, activate:true, update_dt:ISODate("2015-03-01T00:00:00+09:00")},
{no:8, name:"フエラムネ", price:60, variety:[{flavor:"コーラ", ppl:3},{flavor:"いちご", ppl:1}], activate:true, update_dt:ISODate("2015-03-15T00:00:00+09:00")},
{no:9, name:"こざくら餅", price:20, variety:[{flavor:"グレープ", ppl:2},{flavor:"コーラ", ppl:3},{flavor:"フルーツソーダ", ppl:1},{flavor:"ミックス", ppl:2}], activate:true, update_dt:ISODate("2015-03-31T00:00:00+09:00")},
{no:10,name:"たまごアイス", price:10, variety:[{flavor:"ミルク", ppl:1},{flavor:"バニラ", ppl:3},{flavor:"チョコレート", ppl:2}], activate:true, update_dt:ISODate("2015-04-01T00:00:00+09:00")},
{no:11,name:"餅太郎", price:30, activate:true, update_dt:ISODate("2015-04-15T00:00:00+09:00")},
{no:12,name:"あんこ玉", price:10, activate:true, update_dt:ISODate("2015-04-30T00:00:00+09:00")},
{no:13,name:"ラムネ", price:30, drink:true, activate:true, update_dt:ISODate("2015-05-01T00:00:00+09:00")},
{no:14,name:"みかん水", price:40, drink:true, activate:true, update_dt:ISODate("2015-05-15T00:00:00+09:00")},
{no:15,name:"さくら大根", activate:false, update_dt:ISODate("2015-05-15T00:00:00+09:00"), desc:"価格不明"}
])
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 15,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})


collection


createCollection()


definition

db.createCollection(name, options)


コレクションの作成はcreateCollection()を使用して明示的に作成する方法とinsert()で暗黙的に作成する方法があります。

コレクション名を指定してコレクションを作成します。

> db.createCollection("product")

{ "ok" : 1 }

insert時にコレクションが存在しなければ暗黙的に作成します。

> db.product.insert({...})

コレクション作成時に指定するオプションでCapped collectionを作成することができます。

この例ではコレクションサイズの上限を1GB、ドキュメント数を100万件に指定しています。

> db.createCollection("product", {capped:true, size:1073741824, max:1000000})

{ "ok" : 1 }

options (一部)

Field
Type
Description

capped
Boolean
Optional. true/false. trueにした場合sizeの指定も 必要.

autoIndexId
Boolean
Optional. true/false. falseにした場合_idインデックスは作成されません。

size
Number
Optional. コレクションの最大byte数. 最小4KBで256の整数倍で指定.

max
Number
Optional. コレクションの最大ドキュメント数. max値を超えてドキュメントを登録すると古いドキュメントから削除される.

:exclamation: capped collectionはremove()でドキュメントを削除することはできません。

> db.product.remove({_id:ObjectId("55537369d5ce22def8f104e1")})

WriteResult({
"nRemoved" : 0,
"writeError" : {
"code" : 20,
"errmsg" : "cannot remove from a capped collection: test.product"
}
})


MongoDB Reference - db.createCollection

MongoDB Manual - Capped Collections



stats()


syntax

db.collection.stats(options)


コレクションの状態はstats()で確認できます。(下記はサンプルデータ登録後の状態です。)

> db.product.stats()

{
"ns" : "test.product",
"count" : 15,
"size" : 3856,
"avgObjSize" : 257,
"numExtents" : 1,
"storageSize" : 8192,
"lastExtentSize" : 8192,
"paddingFactor" : 1,
"paddingFactorNote" : "paddingFactor is unused and unmaintained in 3.0.
It remains hard coded to 1.0 for compatibility only."
,
"userFlags" : 1,
"capped" : false,
"nindexes" : 1,
"totalIndexSize" : 8176,
"indexSizes" : {
"_id_" : 8176
},
"ok" : 1
}

Field
Description

ns
namespace

count
number of documents

size
collection size in bytes

avgObjSize
average object size in bytes

numExtents
The total number of contiguously allocated data file regions.

storageSize
(pre)allocated space for the collection in bytes

lastExtentSize
The size of the last extent allocated.

paddingFactor
Deprecated since version 3.0.0

paddingFactorNote

userFlags
A number that indicates the user-set flags on the collection.

capped
This field will be “true” if the collection is capped.

max
Shows the maximum number of documents that may be present in a capped collection.

maxSize
Shows the maximum size of a capped collection.

nindexes
number of indexes

totalIndexSize
total index size in bytes

indexSizes
size of specific indexes in bytes


MongoDB Reference - coll Stats


オプションでscaleを1024に設定するとデータサイズがKB単位で表示されます。

> db.product.stats({scale:1024})

その他にも下記の状態確認用メソッドがあります。

> db.product.isCapped()

false
> db.product.dataSize()
3856
> db.product.storageSize()
8192
> db.product.totalSize()
16368
> db.product.totalIndexSize()
8176


find()


definition

db.collection.find(<query>)

db.collection.find(<query>, <projection>)

コレクションからドキュメントを検索します。


無条件で検索する

> db.product.find()

または{}を明示的に渡すことでも無条件の検索になります。

> db.product.find( {} )


条件を指定して検索する

検索条件をfind()の第1引数(query)に記述します。

この例では_idを指定して検索します。

> db.product.find(

{_id: ObjectId("5553d954e8b70b81d56a0383")}
)

nameフィールドが"うまい棒"と等価なドキュメントを検索します。

> db.product.find( {name:"うまい棒"} )

priceフィールドが10と等価なドキュメントを検索します。

> db.product.find( {price:10} )

ただし、次のような比較演算子を使った検索は行えません。

このような検索は後述するQuery Selectorsを使用します。

> db.product.find( {price: >= 10} )

2015-05-17T07:21:21.726+0900 E QUERY SyntaxError: Unexpected token >=


配列要素に対して検索する

フィールドに配列を記述することで配列要素に対する検索が行えます。

> db.product.find( {"variety.flavor":"コーラ"} )

添え字を指定して検索することができます。

この例ではvariety[0].flavorが"コーラ"のドキュメントを検索します。

> db.product.find( {"variety.0.flavor":"コーラ"} )


Query Selectors

$eq,$gte,$existsなどをQuery Selectorといいます。


Comparison Query Operators

$eq, &ne, $gt, $gte, $lt, $lte, $in, $nin


$eq

$eqを使用したnameフィールドが"うまい棒"の検索です。

> db.product.find( {name: {$eq:"うまい棒"}} )


$gte

priceフィールドが50以上のドキュメントを検索します。

> db.product.find( {price: {$gte:50}} )


$lte

priceフィールドが30以下のドキュメントを検索します。

> db.product.find( {price: {$lte:30}} )

priceフィールドが20以上かつ40以下のドキュメントを検索します。

> db.product.find( {price: {$gte:20, $lte:40}} )


$in


syntax

{ field: { $in: [ <value1>, <value2>, ... <valueN> ] } }


priceフィールドが20か40のドキュメントを検索します。

> db.product.find( {price: {$in:[20,40]}} )


$nin


syntax

{ field: { $nin: [ <value1>, <value2> ... <valueN> ] } }


priceフィールドが30および50以外のドキュメントを検索します。

なお、この例のようにpriceフィールドが存在しないドキュメントも検索されます。

> db.product.find( {price: {$nin:[30,50]}} )

priceフィールドが存在しないドキュメントを除外したい場合は$existsも使用します。

> db.product.find(

{$and:[ {price: { $nin:[30,50] }},
{price: { $exists:true} } ]}
)


Logical Query Operators

$or, $and, $not, $nor


$or


syntax

{ $or: [ {<expression1>}, {<expression2>}, ... , {<expressionN>} ] }


update_dtフィールドが4/30か5/01のドキュメントを検索します。

> db.product.find(

{$or:[ {update_dt:{$eq:ISODate("2015-04-30T00:00:00+09:00")}},
{update_dt:{$eq:ISODate("2015-05-01T00:00:00+09:00")}} ]}
)


$and


syntax

{ $and: [ {<expression1>}, {<expression2>} , ... , {<expressionN>} ] }


priceフィールドが10で且つupdate_dtフィールドが1/31のドキュメントを検索します。

> db.product.find(

{$and:[ {price:{$eq:10}},
{update_dt:{$eq:ISODate("2015-01-31T00:00:00+09:00")}} ]}
)


$not


syntax

{ field: { $not: {<operator-expression>} } }


priceフィールドが10ではないドキュメントを検索します。

$ninと同様にpriceフィールドが存在しないドキュメントも検索されます。

> db.product.find( {price: { $not: {$eq:10} }} )

priceフィールドが存在しないドキュメントを除外したい場合は$existsも使用します。

> db.product.find(

{$and:[ {price: { $not:{$eq:10} }},
{price: { $exists:true} } ]}
)


$nor

与えられた式をすべて満たさないドキュメントを検索します。


syntax

{ $nor: [ {<expression1>}, {<expression2>}, ...  {<expressionN>} ] }


この例ではこれらの条件を満たすドキュメントを検索します。


  • priceフィールドが30では無く且つdrinkフィールドがtrueでは無い

  • priceフィールドが30では無く且つdrinkフィールドが存在しない

  • priceフィールドが存在しなく且つdrinkフィールドがtrueでは無い

  • priceフィールドもdrinkフィールドも存在しない

> db.product.find(

{$nor: [{price:30},
{drink:true}]}
)


Element Query Operators

$exists, $type


$exists


syntax

{ field: { $exists: <boolean> } }


drinkフィールドが存在するドキュメントを検索します。

> db.product.find( {drink: {$exists:true}} )


$type


syntax

{ field: { $type: <BSON type> } }


update_dtフィールドがdate型(9)のドキュメントを検索します。

> db.product.find( {update_dt:{$type:9}} )

Available Types

Type
Number
Notes

Double
1

String
2

Object
3

Array
4

Binary data
5

Undefined
6
Deprecated.

Object id
7

Boolean
8

Date
9

Null
10

Regular Expression
11

JavaScript
13

Symbol
14

JavaScript (with scope)
15

32-bit integer
16

Timestamp
17

64-bit integer
18

Min key
255
Query with -1.

Max key
127


MongoDB Reference - BSON TYPE



Evaluation Query Operators

$mod, $regex, $text, $where


$mod

剰余が指定した値と同じドキュメントを検索します。


syntax

{ field: { $mod: [ divisor, remainder ] } }


noフィールドが5の整数倍のドキュメントを検索します。

> db.product.find( {no: {$mod:[5, 0]} } )


$regex

検索条件に正規表現を使用します。


syntax

{ <field>: { $regex: /pattern/, $options: '<options>' } }

{ <field>: { $regex: 'pattern', $options: '<options>' } }
{ <field>: { $regex: /pattern/<options> } }


$text

全文検索を行います。そのためにはtext indexを作成する必要があります。(現時点では日本語は未対応の模様)


syntax

{ $text: { $search: <string>, $language: <string> } }



MongoDB reference - Text search Languages



$where

条件にjavascirptを使用します。


syntax

{ $where: "javascript" }


priceフィールドが10以上20以下のドキュメントを検索します。

> db.product.find(

{$where:"this.price >= 10 && this.price <= 20"}
)


Array Query Operators

$all,$elemMatch,$size


$all

指定された要素をすべて含む配列を持つドキュメントを検索します。


syntax

{ <field>: { $all: [ <value1> , <value2> ... ] } }


> db.product.find(

{"variety.flavor": { $all: ["コーラ", "グレープ"] } }
)

$allを使用しなくても同様の検索を行えます。

> db.product.find(

{$and: [ {"variety.flavor":"コーラ"},
{"variety.flavor":"グレープ"} ] }
)


$elemMatch

条件を満たす配列を持つドキュメントを検索します。


syntax

{ <field>: { $elemMatch: { <query1>, <query2>, ... } } }


> db.product.find(

{variety:{ $elemMatch:{ flavor:{$eq:"コーラ"}, ppl:{$gte:3} } }}
)

$elemMatchを使用しなくても同様の検索を行えます。

> db.product.find(

{$and:[ {"variety.flavor":{$eq:"コーラ"}},
{"variety.ppl":{$gte:3}}]}
)


$size

指定する要素数の配列を持つドキュメントを検索します。


syntax

{ <field>: { $size: <number> } }


> db.product.find(

{variety:{ $size:3 }}
)


取得するフィールドを選択する

取得するフィールドをfind()の第2引数(projection)に記述します。フィールド名とフラグ(1:取得、0:除外)を指定します。(_idは指定しなくても含まれるようです。)

> db.product.find({}, {name:1, price:1})

フィールドに0を指定すると除外することができます。この例では_idを除外しています。

> db.product.find({}, {_id:0, name:1, price:1})


MongoDB Reference - find

MongoDB Reference - Query and Projection Operators



findOne()


definition

db.collection.findOne(<query>)

db.collection.findOne(<query>, <projection>)

find()と同じ使い方ができますが、メソッドの返り値はドキュメントになります。


無条件で検索する

> db.product.findOne()

または

> db.product.findOne({})

返り値はドキュメントなのでフィールドにアクセスできます。

> db.product.findOne({}).name

うまい棒


条件を指定して検索する

条件に一致するドキュメントが複数あっても1件しか取得しません。

> db.product.findOne({price:10})


取得するフィールドを選択する

> db.product.findOne({},{name:1, price:1})


MongoDB Reference - findOne



findAndModify()


definition

db.collection.findAndModify({

query: <document>,
sort: <document>,
remove: <boolean>,
update: <document>,
new: <boolean>,
fields: <document>,
upsert: <boolean>
})


取得と更新を行う

nameフィールドが"うまい棒"のドキュメントを返すと共にpriceフィールドを30に更新します。

> db.product.findAndModify({

query: {name:"うまい棒"},
update: {$set:{price:30}}
})
{
"_id" : ObjectId("5557d59cb636d6666833fb01"),
"no" : 1,
"name" : "うまい棒",
"price" : 10,
"variety" : [
{
"flavor" : "メンタイ",
"ppl" : 3
},
{
"flavor" : "サラミ",
"ppl" : 3
},
{
"flavor" : "ピザ",
"ppl" : 2
},
{
"flavor" : "オニオンサラダ",
"ppl" : 2
},
{
"flavor" : "コーンポタージュ",
"ppl" : 1
}
],
"snack" : true,
"activate" : true,
"update_dt" : ISODate("2014-12-31T15:00:00Z")
}

findAndModify()が更新するドキュメントの件数は1件だけです。もしqueryの条件が複数のドキュメントに一致した場合、更新は最初のドキュメントに行います。

この例ではpriceフィールドが60のドキュメントを対象にしていますが、noフィールドの降順にソートしているため、更新されるのは"すこんぶ"になります。

/* priceフィールドが60のドキュメントは2件 */

> db.product.find({price:60},{_id:0,no:1,name:1,price:1})
{ "no" : 8, "name" : "フエラムネ", "price" : 60 }
{ "no" : 18, "name" : "すこんぶ", "price" : 60 }
> db.product.findAndModify({
query: {price:60},
update: {$set:{price:65}},
sort: {no:-1}
})
{
"_id" : ObjectId("5557c76db636d6666833fb00"),
"no" : 18,
"name" : "すこんぶ",
"activate" : true,
"update_dt" : ISODate("2015-05-31T15:00:00Z"),
"price" : 60
}

queryの条件が一致するドキュメントが存在しなかった場合は、更新も追加もされません。

> db.product.findAndModify({

query: {no:16},
update: {no:16, name:"ボンタンアメ", price:100, activate:false, update_dt:ISODate("2015-05-15T00:00:00+09:00")}
})
null

/* 追加されていないのでドキュメントは見つかりません */
> db.product.find({no:16},{_id:0,no:1,name:1,price:1})
>

upsert:trueを指定すると、queryの条件に一致するドキュメントが見つからなかった場合に追加を行います。

> db.product.findAndModify({

query: {no:16},
update: {no:16, name:"ボンタンアメ", price:100, activate:false, update_dt:ISODate("2015-05-15T00:00:00+09:00")},
upsert:true
})
null

/* upsert:trueを指定することでドキュメントを追加することができました */
> db.product.find({no:16},{_id:0,no:1,name:1,price:1})
{ "no" : 16, "name" : "ボンタンアメ", "price" : 100 }

new:trueを指定すると、更新後の(追加した場合は追加した)ドキュメントを返します。(追加の場合はnullを返します。)

> db.product.findAndModify({

query: {no:17},
update: {no:17, name:"スモモちゃん", price:40, activate:false, update_dt:ISODate("2015-05-30T00:00:00+09:00")},
upsert: true,
new: true
})
{
"_id" : ObjectId("5557c5e436efe7aa0e474d31"),
"no" : 17,
"name" : "スモモちゃん",
"price" : 40,
"activate" : false,
"update_dt" : ISODate("2015-05-29T15:00:00Z")
}


取得と削除を行う

nameフィールドが"うまい棒"のドキュメントを返すと共にそのドキュメントを削除します。

> db.product.findAndModify({

query: {name:"うまい棒"},
remove: true
})
{
"_id" : ObjectId("5557d59cb636d6666833fb01"),
"no" : 1,
"name" : "うまい棒",
"price" : 30,
"variety" : [
{
"flavor" : "メンタイ",
"ppl" : 3
},
{
"flavor" : "サラミ",
"ppl" : 3
},
{
"flavor" : "ピザ",
"ppl" : 2
},
{
"flavor" : "オニオンサラダ",
"ppl" : 2
},
{
"flavor" : "コーンポタージュ",
"ppl" : 1
}
],
"snack" : true,
"activate" : true,
"update_dt" : ISODate("2014-12-31T15:00:00Z")
}
/* 削除されたのでドキュメントは見つかりません */
> db.product.find({name:"うまい棒"})
>


MongoDB Reference - findAndModify



cursorオブジェクト

find()はcursorオブジェクトを返します。cursorオブジェクトにはcount()forEach()limit()sort()などのメソッドがあります。

なお、findOne()はcursorオブジェクトではなくdocumentオブジェクトを返します。

下記のようにcursorオブジェクトを変数に保存して処理を行うことができます。

> var c = db.product.find().limit(3)

> while (c.hasNext()) { print(c.next().name); }
ポテトフライ
きなこ棒
生いきビール


cursorオブジェクトの主なメソッド


count()

カーソルが返すドキュメントの件数を取得します。

> db.product.find().count()

17

コレクションにもcount()がありますので、下記のようにしても件数を取得することができます。

> db.product.count()

17

コレクションのcount()は引数にqueryを渡すことが可能です。

> db.product.count({price:10})

5

findOne()はcursorオブジェクトを返さないためエラーになります。

> db.product.findOne().count()

2015-05-17T07:35:12.954+0900 E QUERY TypeError: Object [object Object] has no
method 'count'
at (shell):1:22


forEach()

検索したドキュメント個々に対して任意の処理を実行します。

> db.product.find().forEach(function(doc){ print(doc.name); })

うまい棒
ポテトフライ
きなこ棒
生いきビール
フルーツヨーグル
コーヒー牛乳キャンディ
ミニコーラ
フエラムネ
こざくら餅
たまごアイス
餅太郎
あんこ玉
ラムネ
みかん水
さくら大根
ボンタンアメ
スモモちゃん


hasNext() / next()

> var cursor = db.product.find()

> while(cursor.hasNext()) {
printjsononeline(cursor.next());
}


limit()

カーソルが返すドキュメントの最大件数を設定します。

> db.product.find({},{_id:0,no:1, name:1,price:1}).limit(5)

{ "no" : 1, "name" : "うまい棒", "price" : 10 }
{ "no" : 2, "name" : "ポテトフライ", "price" : 30 }
{ "no" : 3, "name" : "きなこ棒", "price" : 10 }
{ "no" : 4, "name" : "生いきビール", "price" : 40 }
{ "no" : 5, "name" : "フルーツヨーグル", "price" : 20 }


sort()

カーソルが返すドキュメントの並び順を指定します。ソートしたいフィールド名と並び順を「1:昇順」「-1:降順」で指定します。

> db.product.find({},{_id:0,no:1, name:1,price:1}).sort({price:1, no:1})

{ "no" : 15, "name" : "さくら大根" }
{ "no" : 1, "name" : "うまい棒", "price" : 10 }
{ "no" : 3, "name" : "きなこ棒", "price" : 10 }
{ "no" : 6, "name" : "コーヒー牛乳キャンディ", "price" : 10 }
{ "no" : 10, "name" : "たまごアイス", "price" : 10 }
{ "no" : 12, "name" : "あんこ玉", "price" : 10 }
{ "no" : 5, "name" : "フルーツヨーグル", "price" : 20 }
{ "no" : 9, "name" : "こざくら餅", "price" : 20 }
{ "no" : 2, "name" : "ポテトフライ", "price" : 30 }
{ "no" : 7, "name" : "ミニコーラ", "price" : 30 }
{ "no" : 11, "name" : "餅太郎", "price" : 30 }
{ "no" : 13, "name" : "ラムネ", "price" : 30 }
{ "no" : 4, "name" : "生いきビール", "price" : 40 }
{ "no" : 14, "name" : "みかん水", "price" : 40 }
{ "no" : 17, "name" : "スモモちゃん", "price" : 40 }
{ "no" : 8, "name" : "フエラムネ", "price" : 60 }
{ "no" : 16, "name" : "ボンタンアメ", "price" : 100 }


skip()

カーソルが返すドキュメントを指定した件数だけskipします。

> db.product.find({},{_id:0,no:1,name:1,price:1}).sort({no:1}).skip(5).limit(3)

{ "no" : 6, "name" : "コーヒー牛乳キャンディ", "price" : 10 }
{ "no" : 7, "name" : "ミニコーラ", "price" : 30 }
{ "no" : 8, "name" : "フエラムネ", "price" : 60 }


explain()

クエリの実行計画を確認します。

> db.product.find().explain()

{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.product",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [ ]
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"$and" : [ ]
},
"direction" : "forward"
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "localhost",
"port" : 27017,
"version" : "3.0.2",
"gitVersion" : "6201872043ecbbc0a4cc169b5482dcf385fc464f"
},
"ok" : 1
}


MongoDB Manual - Explan Results



pretty()

ドキュメントを見やすいフォーマットに整形して出力します。

> db.product.find({no:1},{name:1,price:1,variety:1}).pretty()

{
"_id" : ObjectId("5557c280b636d6666833faf1"),
"name" : "うまい棒",
"price" : 10,
"variety" : [
{
"flavor" : "メンタイ",
"ppl" : 3
},
{
"flavor" : "サラミ",
"ppl" : 3
},
{
"flavor" : "ピザ",
"ppl" : 2
},
{
"flavor" : "オニオンサラダ",
"ppl" : 2
},
{
"flavor" : "コーンポタージュ",
"ppl" : 1
}
]
}


MongoDB Manual - Cursors

MongoDB Reference - Cursor methods



insert()


definition

db.collection.insert(

<document or array of documents>,
{ writeConcern: <document>, ordered: <boolean> }
)


新規作成

ドキュメントを作成します。

> db.product.insert({no:18, name:"すこんぶ", price:60, activate:true, update_dt:ISODate("2015-06-01T00:00:00+09:00")})

WriteResult({ "nInserted" : 1 })

insert()は実行結果をWriteResultオブジェクトとして返します。

> var ws = db.product.insert({no:18, name:"すこんぶ", price:60, activate:true, update_dt:ISODate("2015-06-01T00:00:00+09:00")})

> printjson(ws)
{ "nInserted" : 1 }


bulk insert

複数件をまとめてインサートするにはデータを配列で渡します。

> db.product.insert([

{...},
{...},
{...}
])

または、bulkオペレーションメソッドを使用します。

> var bulk = db.product.initializeOrderedBulkOp()

> bulk.insert({...})
> bulk.insert({...})
> bulk.insert({...})
> bulk.execute()

bulkインサートは実行結果をBulkWriteResultとして返します。

> var ws = bulk.execute()

> printjson(ws)
{
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 14,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
}


MongoDB Reference - insert

MongoDB Reference - Bulk Operation Methods



update()


definition

db.collection.update(

<query>,
<update>,
{ upsert: <boolean>, multi: <boolean>, writeConcern: <document> }
)


フィールドの更新

update()の第1引数(query)に更新条件を、第2引数(update)に更新内容を記述します。

$setを使用するとフィールドの値を置換することができます。

> db.product.findOne({name:"うまい棒"}).price

10
> db.product.update(
{name:"うまい棒"},
{$set:{price:25}}
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.product.findOne({name:"うまい棒"}).price
25

$setを使用せず次のような操作を行うとドキュメント自体が更新されます。

> db.product.update(

{_id: ObjectId("5557c280b636d6666833faf1"},
{price:35}
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.product.findOne({_id:ObjectId("5557c280b636d6666833faf1")})
{ "_id" : ObjectId("5557c280b636d6666833faf1"), "price" : 35 }


Update Operators

$set,$unset,$incなどをUpdate Operatorといいます。


$set

上記のとおりです。


$inc

$incを使用するとフィールドの値をインクリメントすることができます。(マイナス値を使用すればデクリメントもできます。)

この例では、"きなこ棒"のpriceフィールドに5を加算します。

> db.product.findOne({name:"きなこ棒"}).price

10
> db.product.update(
{name:"きなこ棒"},
{$inc:{price:5}}
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.product.findOne({name:"きなこ棒"}).price
15


$min / $max

$min/$maxを使用すると条件付きでフィールドの値を変更することができます。

$minを使用すると現在の値より大きい値で更新はできなくなります。($maxはその逆の働きをします。)

この例では、"生いきビール"のpriceフィールドを40から50へ更新しようとしていますが、ドキュメントは更新されません。

> db.product.findOne(

{name:"生いきビール"},
{_id:0, name:1, price:1}
)
{ "name" : "生いきビール", "price" : 40 }
> db.product.update(
{name:"生いきビール"},
{$min:{price:50}}
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })

現在の値より小さい値へ更新することは可能です。

> db.product.update(

{name:"生いきビール"},
{$min:{price:30}}
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.product.findOne(
{name:"生いきビール"},
{_id:0, name:1, price:1}
)
{ "name" : "生いきビール", "price" : 30 }


$currentDate

$currentDateを使用すると指定したフィールドを現在日時で更新することができます。

> db.product.update(

{name:"生いきビール"},
{$currentDate:{update_dt: {$type: "date"}}}
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })


更新対象が見つからなかった場合

queryで指定する更新対象のドキュメントが見つからなかった場合は、ドキュメントは追加も更新もされません。

> db.product.update(

{no:19},
{no:19, name:"ハートチップル", price:100, activate:true, variety:[{flavor:"ニンニク", ppl:2}], snack:true, update_dt:ISODate("2015-06-01T00:00:00+09:00")}
)
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })

upsert:trueを指定すること更新対象がなかった場合にドキュメントを追加することができます。

> db.product.update(

{no:19},
{no:19, name:"ハートチップル", price:100, activate:true, variety:[{flavor:"ニンニク", ppl:2}], snack:true, update_dt:ISODate("2015-06-01T00:00:00+09:00")},
{upsert:true}
)
WriteResult({
"nMatched" : 0,
"nUpserted" : 1,
"nModified" : 0,
"_id" : ObjectId("5557cb2736efe7aa0e474d32")
})


upsertでinsertの時にだけフィールドを更新する

$setOnInsertで指定するフィールドはドキュメントのinsert時にしか更新されません。

この例ではinsert時にだけcreate_dtフィールドを現在日時で更新します。

> db.product.findOne({no:20})

null
> db.product.update(
{no:20},
{$set:{no:20, name:"きびだんご", price:100, activate:true, update_dt:ISODate()}, $setOnInsert:{create_dt:ISODate()}},
{upsert:true}
)
WriteResult({
"nMatched" : 0,
"nUpserted" : 1,
"nModified" : 0,
"_id" : ObjectId("5557cda836efe7aa0e474d34")
})
> db.product.findOne({no:20},{_id:0,no:1,name:1,price:1,update_dt:1,create_dt:1})
{
"no" : 20,
"name" : "きびだんご",
"price" : 100,
"update_dt" : ISODate("2015-05-16T23:07:20.636Z"),
"create_dt" : ISODate("2015-05-16T23:07:20.636Z")
}

priceフィールドの値を変えてもう一度updateを行います。

priceフィールドとupdate_dtフィールドは更新されていますが、create_dtフィールドはinsert時のときのままです。

> db.product.update(

{no:20},
{$set:{no:20, name:"きびだんご", price:120, activate:true, update_dt:ISODate()}, $setOnInsert:{create_dt:ISODate()}},
{upsert:true}
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.product.findOne({no:20},{_id:0,no:1,name:1,price:1,update_dt:1,create_dt:1})
{
"no" : 20,
"name" : "きびだんご",
"price" : 120,
"update_dt" : ISODate("2015-05-16T23:08:13.973Z"),
"create_dt" : ISODate("2015-05-16T23:07:20.636Z")
}


フィールドのリネーム

フィールドをリネームするには$renameを使用します。ドキュメント全てを対象にする場合はmulti:trueを指定します。

> db.product.update(

{},
{$rename:{"price":"unit_price"}}, {multi:true}
)
WriteResult({ "nMatched" : 19, "nUpserted" : 0, "nModified" : 18 })
/* priceフィールドがunit_priceフィールドに変わっています */
> db.product.find({}, {_id:0, name:1, price:1, unit_price:1}).limit(5)
{ "name" : "ポテトフライ", "unit_price" : 30 }
{ "name" : "きなこ棒", "unit_price" : 15 }
{ "name" : "生いきビール", "unit_price" : 30 }
{ "name" : "フルーツヨーグル", "unit_price" : 20 }
{ "name" : "コーヒー牛乳キャンディ", "unit_price" : 10 }


複数件の更新

複数のドキュメントが更新対象になる場合、実際に更新されるのは最初の1件だけです。

> db.product.find({price:10},{_id:0,name:1,price:1})

{ "name" : "うまい棒", "price" : 10 }
{ "name" : "コーヒー牛乳キャンディ", "price" : 10 }
{ "name" : "たまごアイス", "price" : 10 }
{ "name" : "あんこ玉", "price" : 10 }
> db.product.update(
{price:10},
{$set:{price:15}}
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

条件に一致する全てのドキュメントを更新するには、multi:trueを指定します。

> db.product.update(

{price:10},
{$set:{price:15}},
{multi:true}
)
WriteResult({ "nMatched" : 4, "nUpserted" : 0, "nModified" : 4 })


フィールドの追加

更新するフィールドがドキュメントに無い場合は、そのフィールドがドキュメントに追加されます。

この例では、"うまい棒"のドキュメントにdescフィールドを追加しています。

> db.product.update(

{name:"うまい棒"},
{$set:{desc:"伝統のスナック菓子"}}
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.product.find({name:"うまい棒"}).pretty()
{
"_id" : ObjectId("5557d975b636d6666833fb02"),
"no" : 1,
"name" : "うまい棒",
"price" : 10,
"variety" : [
{
"flavor" : "メンタイ",
"ppl" : 3
},
{
"flavor" : "サラミ",
"ppl" : 3
},
{
"flavor" : "ピザ",
"ppl" : 2
},
{
"flavor" : "オニオンサラダ",
"ppl" : 2
},
{
"flavor" : "コーンポタージュ",
"ppl" : 1
}
],
"snack" : true,
"activate" : true,
"update_dt" : ISODate("2014-12-31T15:00:00Z"),
"desc" : "伝統のスナック菓子"
}


フィールドの削除

$unsetを使用するとドキュメントからフィールドを削除することができます。

> db.product.update(

{name:"うまい棒"},
{$unset:{price:""}}
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.product.find({name:"うまい棒"}).pretty()
{
"_id" : ObjectId("5557d975b636d6666833fb02"),
"no" : 1,
"name" : "うまい棒",
"variety" : [
{
"flavor" : "メンタイ",
"ppl" : 3
},
{
"flavor" : "サラミ",
"ppl" : 3
},
{
"flavor" : "ピザ",
"ppl" : 2
},
{
"flavor" : "オニオンサラダ",
"ppl" : 2
},
{
"flavor" : "コーンポタージュ",
"ppl" : 1
}
],
"snack" : true,
"activate" : true,
"update_dt" : ISODate("2014-12-31T15:00:00Z"),
"desc" : "伝統のスナック菓子"
}


MongoDB Reference - update

MongoDB Reference - Update Operators



save()


definition

db.collection.save(

<document>,
{ writeConcern: <document> }
)


追加または更新

update()は更新対象のドキュメントをqueryで指定できますが、save()はqueryを指定することはできません。

代わりに_idが指定されていて当該のドキュメントがあればupdateを行い、無ければinsertします。

> db.product.save(

{no:21, name:"ふ菓子", price:10, activate:false, update_dt:ISODate("2015-05-30T00:00:00+09:00")}
)
WriteResult({ "nInserted" : 1 })

_idが指定されていて且つそのid値が存在する場合は更新します。(id値が存在しない場合は追加)

> db.product.save(

{_id:ObjectId("5557daa5b636d6666833fb03"), no:21, name:"ふ菓子", price:20, activate:true, update_dt:ISODate("2015-05-30T00:00:00+09:00")}
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })


update()との違い


  • queryで更新対象を指定できない

  • 複数件の同時更新ができない

  • upadte()、findAndModify()では使用できるupdate operatorが使用できない


MongoDB Reference - save



remove()


definition

db.collection.remove(

<query>,
<justOne>
)


すべて削除

> db.product.remove({})

WriteResult({ "nRemoved" : 14 })


条件を指定して削除

> db.product.remove({activate:false})

WriteResult({ "nRemoved" : 2 })


1件だけ削除

第2引数(justOne)にtrueを渡すと1件だけ削除します。

> db.product.remove({}, true)

WriteResult({ "nRemoved" : 1 })

remove()は実行結果をWriteResultオブジェクトとして返します。

> var wr = db.product.remove({}, true)

> printjson(wr)
{ "nRemoved" : 1 }


MongoDB Reference - remove



index


indexの確認

> db.product.getIndexes()

[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.product"
}
]


indexの作成


definition

db.collection.createIndex(keys, options)


フィールドに1を指定すると昇順、-1を指定すると降順になります。

> db.product.createIndex({price:1})

{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
/* 作成したインデックスを確認してみます */
> db.product.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.product"
},
{
"v" : 1,
"key" : {
"price" : 1
},
"name" : "price_1",
"ns" : "test.product"
},
]
/* 名前を指定して削除します */
> db.product.dropIndex("price_1")
{ "nIndexesWas" : 2, "ok" : 1 }

オプションでindex名を指定することができます。

> db.product.createIndex(

{price:1},
{name:"price_idx01"}
)
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}


ユニークindexの作成

作成時のオプションでunique:trueを指定します。

> db.product.createIndex(

{name:1},
{unique:true, name:"name_uni01"}
)
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 2,
"numIndexesAfter" : 3,
"ok" : 1
}

ユニークindexを作成したフィールドには重複したデータを登録することはできませんが、追加するドキュメントにそのフィールドが無かった場合、フィールドの値はnullとして扱われるようです。


MongoDB manual - unique index and missing field


試しに、nameフィールドにユニークindexを作成した状態で、nameフィールドが無いドキュメントを追加してみます。

1件目は追加することができました。

> db.product.insert(

{no:22, price:30, activate:true, update_dt:ISODate("2015-05-30T00:00:00+09:00")}
)
WriteResult({ "nInserted" : 1 })

もう一度nameフィールドが無いドキュメントを追加しようとするとエラーになります。これはnull値も重複のチェックの対象になっているためのようです。

> db.product.insert(

{no:23, price:30, activate:true, update_dt:ISODate("2015-05-30T00:00:00+09:00")}
)
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error index: test.product.$name
_uni01 dup key: { : null }"

}
})

この場合は、ユニークindex作成時にsparse:trueを併用することでnullを無視することができます。

/* ユニークindexを作り直すために削除 */

> db.product.dropIndex("name_uni01")
{ "nIndexesWas" : 3, "ok" : 1 }
/* ユニークindexを作成 */
> db.product.createIndex(
{name:1},
{unique:true, sparse:true, name:"name_uni01"}
)
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 2,
"numIndexesAfter" : 3,
"ok" : 1
}
/* nameフィールドの無いドキュメントを追加 */
> db.product.insert(
{no:23, price:30, activate:true, update_dt:ISODate(
"2015-05-30T00:00:00+09:00")}
)
WriteResult({ "nInserted" : 1 })
/* nameフィールドの無いドキュメントを追加することができました */
> db.product.find({name:{$exists:false}},{_id:1,no:1,name:1})
{ "_id" : ObjectId("5557db82b636d6666833fb04"), "no" : 22 }
{ "_id" : ObjectId("5557dbf5b636d6666833fb06"), "no" : 23 }


TTLインデックス

時間経過によってドキュメントを自動的に削除したい場合、expireAfterSecondsを使用したインデックスを作成します。

この例ではdelete_dtフィールドにexpireAfterSecondsを300秒(5分)に設定したTTLインデックスを作成しています。

> db.product.createIndex(

{delete_dt:1},
{expireAfterSeconds:300, name:"ttl_idx"}
)
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 3,
"numIndexesAfter" : 4,
"ok" : 1
}

ためしに"コーヒー牛乳キャンディ"のドキュメントのdelete_dtを現在日時で更新します。

更新してから5分経過後にもう一度検索すると削除されていることがわかります。

> db.product.update(

{name:"コーヒー牛乳キャンディ"},
{$set:{delete_dt:new Date()}}
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.product.find(
{name:"コーヒー牛乳キャンディ"},
{_id:0,name:1,delete_dt:1}
)
{ "name" : "コーヒー牛乳キャンディ", "delete_dt" : "Sun May 17 2015 09:10:36 GMT
+0900 (東京 (標準時))"
}

5分経過後に検索するとドキュメントは見つかりません。

> db.product.find(

{name:"コーヒー牛乳キャンディ"},
{_id:0,name:1,delete_dt:1}
)
>


MongoDB Reference - createIndex

MongoDB Manual - Sparse Indexes

MongoDB Manual - Expire Data from Collections by Setting TTL



indexの削除

インデックスの名前を指定して削除します。

> db.product.dropIndex("price_idx01")

{ "nIndexesWas" : 4, "ok" : 1 }

"product"コレクションの(_id以外の)すべてのindexを削除します。

> db.product.dropIndexes()

{
"nIndexesWas" : 3,
"msg" : "non-_id indexes dropped for collection",
"ok" : 1
}


rename


definition

db.collection.renameCollection(target, dropTarget)


"product"コレクションの名前を"newProduct"にリネームします。

> db.product.renameCollection("newProduct")

{ "ok" : 1 }

指定した"newProduct"コレクションが既に存在する場合はエラーになります。

{ "ok" : 0, "errmsg" : "target namespace exists" }

第2引数(dropTarget)にtrueを指定した場合、既に"newProduct"コレクションがある場合はそのコレクションを削除し、その後に"product"を"newProduct"へリネームします。

> db.product.renameCollection("newProduct", true)

{ "ok" : 1 }


MongoDB Reference - RenameCollection



drop()


definition

db.collection.drop()


"product"コレクションを削除します。

> db.product.drop()

true


MongoDB Reference - drop



store javascript function


登録する

> db.system.js.save({

_id:"add",
value:function(a, b) { return a + b; }
})
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : "add" })


登録されているfunctionを調べる

> db.system.js.find()

{ "_id" : "add", "value" : function (a, b) { return a + b; } }


使用する

> db.loadServerScripts()

> var f = db.system.js.findOne({_id:"add"}).value
> f(2,3)
5


削除する

> db.system.js.remove({_id:"add"})

WriteResult({ "nRemoved" : 1 })


MongoDB Manual - store javascript function



日付


Date()

Unixエポックからのミリ秒数(1970年1月1日)を表す64ビットの整数です。

> var dt = new Date()

> dt.toString()
Sun May 17 2015 06:25:43 GMT+0900 (東京 (標準時))


ISODate()

Date()のラッパー関数で返される値はDateです。

> var iso = ISODate()

> iso.toString()
Sun May 17 2015 06:25:43 GMT+0900 (東京 (標準時))
> iso instanceof Date
true
> iso instanceof ISODate
false

任意の日時を生成するにはISODate()に基本形式か拡張形式の日時表記文字列を渡します。


基本形式

"20150510T102322+0900"

拡張形式

"2015-05-10T10:23:22+09:00"

世界協定時(UTC)として表現する場合は最後に"Z"を付けます。

ISODate("2015-05-10T00:00:00Z")

日本標準時(UTC+9)の場合は"+0900"または"+09:00"を付けます。

ISODate("2015-05-10T09:00:00+09:00")

> var iso = ISODate("2015-05-15T12:00:01+09:00")

> iso.toString()
Fri May 15 2015 12:00:01 GMT+0900 (東京 (標準時))


Timestamp()

MongoDB内部で使用されているデータ型で、通常のアプリケーションではDate型で十分らしいです。

> var ts = new Timestamp()

> ts.toString()
Timestamp(0, 0)


MongoDB reference - Date

MongoDB reference - Timpstamps



shellのカスタマイズ

find()の一度に取得する件数を変えます。デフォルトは20です。

> DBQuery.shellBatchSize = 10

10

shellの出力のデフォルトをpretty printにします。

> DBQuery.prototype._prettyShell = true

true

下記のようなjavascriptを実行してpromptをカスタマイズできます。

> cmdCount = 1;

> host = db.serverStatus().host;
> prompt = function() {
return db + "@" + host + "(" + (cmdCount++) + ")> ";
}
test@localhost(1)>

.mongorc.js

ホームディレクトリにある.mongorc.jsに、shell起動時に実行したいスクリプトを記述することができます。


MongoDB Manual - Getting Started with the mongo Shell



Native Methods


load()

load()は引数で指定されたjavascriptファイルをロードして実行します。

この例では、下記のjavascriptをsample.jsファイルとして用意しmongo shellにロードします。


sample.js

function randomStr() {

return Math.random().toString(36);
}

var col = new Array("red","blue","yellow","green","white");

function randomColor() {
return col[Math.floor(Math.random() * 5)];
}

var act = new Array(true, false);

function randomAct() {
return act[Math.floor(Math.random() * 2)];
}

function createTestData() {
for (var idx = 0; idx<100000; idx++) {
db.sample.insert({no:idx, color:randomColor(), desc:randomStr(), activate:randomAct(), create_dt:new Date()});
}
}


sample.jsをロードします。

> load("sample.js")

true

createTestData()を実行するとsampleコレクションにテストデータを10万件作成します。

> createTestData()

> db.sample.find().count()
100000

その他の主なNativeメソッド

Name
Description

cat()
Returns the contents of the specified file.

version()
Returns the current version of the mongo shell instance.

hostname()
Returns the hostname of the system running the shell.

load()
Loads and runs a JavaScript file in the shell.

ls()
Returns a list of the files in the current directory.

quit()
Exits the current shell session.

_rand()
Returns a random number between 0 and 1.


MongoDB Reference - Native Methods