mongo shellの操作まとめ

# 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:小)  |

**サンプルデータの準備**

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

```js: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()

```js:definition
db.createCollection(name, options)
```

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

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

```js
> db.createCollection("product")
{ "ok" : 1 }
```

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

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

コレクション作成時に指定するオプションでCapped collectionを作成することができます。
この例ではコレクションサイズの上限を1GB、ドキュメント数を100万件に指定しています。

```js
> 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()でドキュメントを削除することはできません。

```js
> 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](http://docs.mongodb.org/manual/reference/method/db.createCollection/)
> [MongoDB Manual - Capped Collections](http://docs.mongodb.org/manual/core/capped-collections/)

### stats()

```js:syntax
db.collection.stats(options)
```

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

```js
> 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](http://docs.mongodb.org/manual/reference/command/collStats/)

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

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

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

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

## find()

```js:definition
db.collection.find(<query>)
db.collection.find(<query>, <projection>)
```

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

### 無条件で検索する

```js
> db.product.find()
```

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

```js
> db.product.find( {} )
```

### 条件を指定して検索する

検索条件を`find()`の第1引数(query)に記述します。
この例では`_id`を指定して検索します。

```js
> db.product.find(
  {_id: ObjectId("5553d954e8b70b81d56a0383")}
)
```

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

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

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

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

ただし、次のような比較演算子を使った検索は行えません。
このような検索は後述するQuery Selectorsを使用します。

```js
> db.product.find( {price: >= 10} )
2015-05-17T07:21:21.726+0900 E QUERY    SyntaxError: Unexpected token >=
```

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

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

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

添え字を指定して検索することができます。
この例ではvariety[0].flavorが"コーラ"のドキュメントを検索します。

```js
> 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フィールドが"うまい棒"の検索です。

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

##### $gte

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

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

##### $lte

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

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

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

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

##### $in

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

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

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

##### $nin

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

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

```js
> db.product.find( {price: {$nin:[30,50]}} )
```
priceフィールドが存在しないドキュメントを除外したい場合は`$exists`も使用します。

```js
> db.product.find(
  {$and:[ {price: { $nin:[30,50] }},
          {price: { $exists:true} } ]}
)
```

#### Logical Query Operators

`$or`, `$and`, `$not`, `$nor`

##### $or

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

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

```js
> 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

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

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

```js
> db.product.find(
  {$and:[ {price:{$eq:10}},
          {update_dt:{$eq:ISODate("2015-01-31T00:00:00+09:00")}} ]}
)
```

##### $not

```js:syntax
{ field: { $not: {<operator-expression>} } }
```

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

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

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

```js
> db.product.find(
  {$and:[ {price: { $not:{$eq:10} }},
          {price: { $exists:true} } ]}
)
```

##### $nor

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

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

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

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

```js
> db.product.find(
  {$nor: [{price:30},
          {drink:true}]}
)
```

#### Element Query Operators

`$exists`, `$type`

##### $exists

```js:syntax
{ field: { $exists: <boolean> } }
```

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

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

##### $type

```js:syntax
{ field: { $type: <BSON type> } }
```

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

```js
> 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](http://docs.mongodb.org/manual/reference/bson-types/)

#### Evaluation Query Operators

`$mod`, `$regex`, `$text`, `$where`

##### $mod

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

```js:syntax
{ field: { $mod: [ divisor, remainder ] } }
```

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

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

##### $regex

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

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

##### $text

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

```js:syntax
{ $text: { $search: <string>, $language: <string> } }
```

> [MongoDB reference - Text search Languages] (http://docs.mongodb.org/manual/reference/text-search-languages/)

##### $where

条件にjavascirptを使用します。

```js:syntax
{ $where: "javascript" }
```

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

```js
> db.product.find(
  {$where:"this.price >= 10 && this.price <= 20"}
)
```

#### Array Query Operators

`$all`,`$elemMatch`,`$size`

##### $all

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

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

```js
> db.product.find(
  {"variety.flavor": { $all: ["コーラ", "グレープ"] } }
)
```

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

```js
> db.product.find(
  {$and: [ {"variety.flavor":"コーラ"},
           {"variety.flavor":"グレープ"} ] }
)
```

##### $elemMatch

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

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

```js
> db.product.find(
  {variety:{ $elemMatch:{ flavor:{$eq:"コーラ"}, ppl:{$gte:3} } }}
)
```

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

```js
> db.product.find(
  {$and:[ {"variety.flavor":{$eq:"コーラ"}},
          {"variety.ppl":{$gte:3}}]}
)
```

##### $size

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

```js:syntax
{ <field>: { $size: <number> } }
```

```js
> db.product.find(
  {variety:{ $size:3 }}
)
```

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

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

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

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

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

> [MongoDB Reference - find](http://docs.mongodb.org/manual/reference/method/db.collection.find/)
> [MongoDB Reference - Query and Projection Operators](http://docs.mongodb.org/manual/reference/operator/query/)

## findOne()

```js:definition
db.collection.findOne(<query>)
db.collection.findOne(<query>, <projection>)
```

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

### 無条件で検索する

```js
> db.product.findOne()
```

または

```js
> db.product.findOne({})
```

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

```js
> db.product.findOne({}).name
うまい棒
```

### 条件を指定して検索する

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

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

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

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

> [MongoDB Reference - findOne](http://docs.mongodb.org/manual/reference/method/db.collection.findOne/)

## findAndModify()

```js:definition
db.collection.findAndModify({
    query: <document>,
    sort: <document>,
    remove: <boolean>,
    update: <document>,
    new: <boolean>,
    fields: <document>,
    upsert: <boolean>
})
```

### 取得と更新を行う

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

```js
> 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フィールドの降順にソートしているため、更新されるのは"すこんぶ"になります。

```js
/* 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の条件が一致するドキュメントが存在しなかった場合は、更新も追加もされません。

```js
> 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の条件に一致するドキュメントが見つからなかった場合に追加を行います。

```js
> 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を返します。)

```js
> 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フィールドが"うまい棒"のドキュメントを返すと共にそのドキュメントを削除します。

```js
> 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] (http://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/)

## cursorオブジェクト

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

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

```js
> var c = db.product.find().limit(3)
> while (c.hasNext()) { print(c.next().name); }
ポテトフライ
きなこ棒
生いきビール
```

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

#### count()

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

```js
> db.product.find().count()
17
```

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

```js
> db.product.count()
17
```

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

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

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

```js
> 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()

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

```js
> db.product.find().forEach(function(doc){ print(doc.name); })
うまい棒
ポテトフライ
きなこ棒
生いきビール
フルーツヨーグル
コーヒー牛乳キャンディ
ミニコーラ
フエラムネ
こざくら餅
たまごアイス
餅太郎
あんこ玉
ラムネ
みかん水
さくら大根
ボンタンアメ
スモモちゃん
```

#### hasNext() / next()

```js
> var cursor = db.product.find()
> while(cursor.hasNext()) {
    printjsononeline(cursor.next());
}
```

#### limit()

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

```js
> 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:降順」で指定します。

```js
> 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します。

```js
> 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()

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

```js
> 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](http://docs.mongodb.org/manual/reference/explain-results/)

#### pretty()

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

```js
> 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] (http://docs.mongodb.org/manual/core/cursors/)
> [MongoDB Reference - Cursor methods](http://docs.mongodb.org/manual/reference/method/js-cursor/)

## insert()

```js:definition
db.collection.insert(
    <document or array of documents>,
    { writeConcern: <document>, ordered: <boolean>  }
)
```

### 新規作成

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

```js
> 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オブジェクトとして返します。

```js
> 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

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

```js
> db.product.insert([
  {...},
  {...},
  {...}
])
```

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

```js
> var bulk = db.product.initializeOrderedBulkOp()
> bulk.insert({...})
> bulk.insert({...})
> bulk.insert({...})
> bulk.execute()
```

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

```js
> var ws = bulk.execute()
> printjson(ws)
{
        "writeErrors" : [ ],
        "writeConcernErrors" : [ ],
        "nInserted" : 14,
        "nUpserted" : 0,
        "nMatched" : 0,
        "nModified" : 0,
        "nRemoved" : 0,
        "upserted" : [ ]
}
```

> [MongoDB Reference - insert](http://docs.mongodb.org/manual/reference/method/db.collection.insert/)
> [MongoDB Reference - Bulk Operation Methods](http://docs.mongodb.org/manual/reference/method/js-bulk/)

## update()

```js:definition
db.collection.update(
   <query>,
   <update>,
   { upsert: <boolean>, multi: <boolean>, writeConcern: <document> }
)
```

### フィールドの更新

`update()`の第1引数(query)に更新条件を、第2引数(update)に更新内容を記述します。
`$set`を使用するとフィールドの値を置換することができます。

```js
> 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`を使用せず次のような操作を行うとドキュメント自体が更新されます。

```js
> 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を加算します。

```js
> 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へ更新しようとしていますが、ドキュメントは更新されません。

```js
> 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 })
```

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

```js
> 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`を使用すると指定したフィールドを現在日時で更新することができます。

```js
> db.product.update(
  {name:"生いきビール"},
  {$currentDate:{update_dt: {$type: "date"}}}
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
```

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

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

```js
> 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`を指定すること更新対象がなかった場合にドキュメントを追加することができます。

```js
> 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フィールドを現在日時で更新します。

```js
> 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時のときのままです。

```js
> 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`を指定します。

```js
> 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件だけです。

```js
> 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`を指定します。

```js
> db.product.update(
  {price:10},
  {$set:{price:15}},
  {multi:true}
)
WriteResult({ "nMatched" : 4, "nUpserted" : 0, "nModified" : 4 })
```

### フィールドの追加

更新するフィールドがドキュメントに無い場合は、そのフィールドがドキュメントに追加されます。
この例では、"うまい棒"のドキュメントにdescフィールドを追加しています。

```js
> 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`を使用するとドキュメントからフィールドを削除することができます。

```js
> 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](http://docs.mongodb.org/manual/reference/method/db.collection.update/)
> [MongoDB Reference - Update Operators](http://docs.mongodb.org/manual/reference/operator/update/)

## save()

```js:definition
db.collection.save(
   <document>,
   { writeConcern: <document> }
)
```

### 追加または更新

`update()`は更新対象のドキュメントをqueryで指定できますが、`save()`はqueryを指定することはできません。
代わりに`_id`が指定されていて当該のドキュメントがあればupdateを行い、無ければinsertします。

```js
> 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値が存在しない場合は追加)

```js
> 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](http://docs.mongodb.org/manual/reference/method/db.collection.save/)

## remove()

```js:definition
db.collection.remove(
   <query>,
   <justOne>
)
```

### すべて削除

```js
> db.product.remove({})
WriteResult({ "nRemoved" : 14 })
```

### 条件を指定して削除

```js
> db.product.remove({activate:false})
WriteResult({ "nRemoved" : 2 })
```

### 1件だけ削除

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

```js
> db.product.remove({}, true)
WriteResult({ "nRemoved" : 1 })
```

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

```js
> var wr = db.product.remove({}, true)
> printjson(wr)
{ "nRemoved" : 1 }
```

> [MongoDB Reference - remove](http://docs.mongodb.org/manual/reference/method/db.collection.remove/)

## index

### indexの確認

```js
> db.product.getIndexes()
[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "test.product"
        }
]
```

### indexの作成

```js:definition
db.collection.createIndex(keys, options)
```

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

```js
> 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名を指定することができます。

```js
> db.product.createIndex(
  {price:1},
  {name:"price_idx01"}
)
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}
```

### ユニークindexの作成

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

```js
> 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] (http://docs.mongodb.org/manual/tutorial/create-a-unique-index/#unique-index-and-missing-field)

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

```js
> db.product.insert(
  {no:22, price:30, activate:true, update_dt:ISODate("2015-05-30T00:00:00+09:00")}
)
WriteResult({ "nInserted" : 1 })
```

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

```js
> 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を無視することができます。

```js
/* ユニーク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インデックスを作成しています。

```js
> db.product.createIndex(
  {delete_dt:1},
  {expireAfterSeconds:300, name:"ttl_idx"}
)
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 3,
        "numIndexesAfter" : 4,
        "ok" : 1
}
```

ためしに"コーヒー牛乳キャンディ"のドキュメントのdelete_dtを現在日時で更新します。
更新してから5分経過後にもう一度検索すると削除されていることがわかります。

```js
> 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分経過後に検索するとドキュメントは見つかりません。

```js
> db.product.find(
  {name:"コーヒー牛乳キャンディ"},
  {_id:0,name:1,delete_dt:1}
)
>
```

> [MongoDB Reference - createIndex](http://docs.mongodb.org/manual/reference/method/db.collection.createIndex/)
> [MongoDB Manual - Sparse Indexes](http://docs.mongodb.org/manual/core/index-sparse/)
> [MongoDB Manual - Expire Data from Collections by Setting TTL](http://docs.mongodb.org/manual/tutorial/expire-data/)

### indexの削除

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

```js
> db.product.dropIndex("price_idx01")
{ "nIndexesWas" : 4, "ok" : 1 }
```

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

```js
> db.product.dropIndexes()
{
        "nIndexesWas" : 3,
        "msg" : "non-_id indexes dropped for collection",
        "ok" : 1
}
```

## rename

```js:definition
db.collection.renameCollection(target, dropTarget)
```

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

```js
> db.product.renameCollection("newProduct")
{ "ok" : 1 }
```

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

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

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

```js
> db.product.renameCollection("newProduct", true)
{ "ok" : 1 }
```

> [MongoDB Reference - RenameCollection](http://docs.mongodb.org/manual/reference/method/db.collection.renameCollection/)

## drop()

```js:definition
db.collection.drop()
```

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

```js
> db.product.drop()
true
```

> [MongoDB Reference - drop](http://docs.mongodb.org/manual/reference/method/db.collection.drop/)

## store javascript function

### 登録する

```js
> db.system.js.save({
    _id:"add",
    value:function(a, b) { return a + b; }
})
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : "add" })
```

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

```js
> db.system.js.find()
{ "_id" : "add", "value" : function (a, b) { return a + b; } }
```

### 使用する

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

### 削除する

```js
> db.system.js.remove({_id:"add"})
WriteResult({ "nRemoved" : 1 })
```

> [MongoDB Manual - store javascript function](http://docs.mongodb.org/manual/tutorial/store-javascript-function-on-server/)

## 日付

### Date()

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

```js
> var dt = new Date()
> dt.toString()
Sun May 17 2015 06:25:43 GMT+0900 (東京 (標準時))
```

### ISODate()

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

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

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

<dl>
  <dt>基本形式</dt>
  <dd>"20150510T102322+0900"</dd>
  <dt>拡張形式</dt>
  <dd>"2015-05-10T10:23:22+09:00"</dd>
</dl>

世界協定時(UTC)として表現する場合は最後に"Z"を付けます。
`ISODate("2015-05-10T00:00:00Z")`

日本標準時(UTC+9)の場合は"+0900"または"+09:00"を付けます。
`ISODate("2015-05-10T09:00:00+09:00")`

```js
> var iso = ISODate("2015-05-15T12:00:01+09:00")
> iso.toString()
Fri May 15 2015 12:00:01 GMT+0900 (東京 (標準時))
```

### Timestamp()

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

```js
> var ts = new Timestamp()
> ts.toString()
Timestamp(0, 0)
```

> [MongoDB reference - Date] (http://docs.mongodb.org/manual/reference/bson-types/#date)
> [MongoDB reference - Timpstamps] (http://docs.mongodb.org/manual/reference/bson-types/#timestamps)


## shellのカスタマイズ

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

```js
> DBQuery.shellBatchSize = 10
10
```

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

```js
> DBQuery.prototype._prettyShell = true
true
```

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

```js
> 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](http://docs.mongodb.org/manual/tutorial/getting-started-with-the-mongo-shell/)

## Native Methods

### load()

`load()`は引数で指定されたjavascriptファイルをロードして実行します。
この例では、下記のjavascriptをsample.jsファイルとして用意しmongo shellにロードします。

```js: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をロードします。

```js
> load("sample.js")
true
```

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

```js
> 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](http://docs.mongodb.org/manual/reference/method/js-native/)