Mongodb-quick-guide

提供:Dev Guides
移動先:案内検索

MongoDB-概要

MongoDBは、高性能、高可用性、および容易なスケーラビリティを提供するクロスプラットフォームのドキュメント指向データベースです。 MongoDBは、コレクションとドキュメントの概念に基づいて機能します。

データベース

データベースは、コレクションの物理的なコンテナです。 各データベースは、ファイルシステム上の独自のファイルセットを取得します。 通常、単一のMongoDBサーバーには複数のデータベースがあります。

コレクション

コレクションは、MongoDBドキュメントのグループです。 これは、RDBMSテーブルと同等です。 コレクションは単一のデータベース内に存在します。 コレクションはスキーマを強制しません。 コレクション内のドキュメントには、異なるフィールドを含めることができます。 通常、コレクション内のすべてのドキュメントは、類似または関連する目的のものです。

資料

ドキュメントは、キーと値のペアのセットです。 ドキュメントには動的スキーマがあります。 動的スキーマとは、同じコレクション内のドキュメントが同じフィールドまたは構造のセットを持つ必要はなく、コレクションのドキュメント内の共通フィールドが異なるタイプのデータを保持できることを意味します。

次の表に、RDBMSの用語とMongoDBの関係を示します。

RDBMS

MongoDB

データベース

データベース

コレクション

タプル/行

資料

カラム

フィールド

テーブル結合

埋め込み文書

主キー

主キー(MongoDB自体によって提供されるデフォルトのキー_id)

データベースサーバーとクライアント

mysqld/Oracle

モンゴド

mysql/sqlplus

モンゴ

サンプル文書

次の例は、ブログサイトのドキュメント構造を示しています。これは、単純にコンマ区切りのキーと値のペアです。

{
   _id: ObjectId(7df78ad8902c)
   title: 'MongoDB Overview',
   description: 'MongoDB is no sql database',
   by: 'tutorials point',
   url: 'http://www.finddevguides.com',
   tags: ['mongodb', 'database', 'NoSQL'],
   likes: 100,
   comments: [
      {
         user:'user1',
         message: 'My first comment',
         dateCreated: new Date(2011,1,20,2,15),
         like: 0
      },
      {
         user:'user2',
         message: 'My second comments',
         dateCreated: new Date(2011,1,25,7,45),
         like: 5
      }
   ]
}
*_id* は、すべてのドキュメントの一意性を保証する12バイトの16進数です。 ドキュメントを挿入するときに_idを指定できます。 指定しない場合、MongoDBはすべてのドキュメントに一意のIDを提供します。 これらの12バイトは、現在のタイムスタンプの最初の4バイト、マシンIDの次の3バイト、MongoDBサーバーのプロセスIDの次の2バイト、残りの3バイトは単純な増分値です。

MongoDB-利点

リレーショナルデータベースには、テーブルの数とこれらのテーブル間の関係を示す典型的なスキーマ設計があります。 MongoDBでは、関係の概念はありません。

RDBMSに対するMongoDBの利点

  • Schema less -MongoDBは、1つのコレクションが異なるドキュメントを保持するドキュメントデータベースです。 文書のフィールド数、内容、サイズは、文書ごとに異なる場合があります。
  • 単一のオブジェクトの構造は明確です。
  • 複雑な結合はありません。
  • 深いクエリ機能。 MongoDBは、SQLとほぼ同等の強力なドキュメントベースのクエリ言語を使用して、ドキュメントの動的クエリをサポートしています。
  • チューニング。
  • スケールアウトの容易さ-MongoDBは簡単にスケールできます。
  • アプリケーションオブジェクトのデータベースオブジェクトへの変換/マッピングは不要です。
  • (ウィンドウ化された)ワーキングセットを格納するために内部メモリを使用し、データへのアクセスを高速化します。

MongoDBを使用する理由

  • ドキュメント指向ストレージ-データはJSONスタイルのドキュメントの形式で保存されます。
  • 任意の属性のインデックス
  • レプリケーションと高可用性
  • 自動シャーディング
  • 豊富なクエリ
  • 迅速なインプレース更新
  • MongoDBによるプロフェッショナルサポート

MongoDBを使用する場所

  • ビッグデータ
  • コンテンツ管理と配信
  • モバイルおよび社会インフラ
  • ユーザーデータ管理
  • データハブ

MongoDB-環境

WindowsにMongoDBをインストールする方法を見てみましょう。

WindowsにMongoDBをインストールする

WindowsにMongoDBをインストールするには、まずhttps://www.mongodb.org/downloadsからMongoDBの最新リリースをダウンロードします。 Windowsのバージョンに応じて、MongoDBの正しいバージョンを取得してください。 Windowsバージョンを取得するには、コマンドプロンプトを開き、次のコマンドを実行します。

C:\>wmic os get osarchitecture
OSArchitecture
64-bit
C:\>

MongoDBの32ビットバージョンは、2GB未満のデータベースのみをサポートし、テストおよび評価の目的にのみ適しています。

ダウンロードしたファイルをc:\ドライブまたはその他の場所に解凍します。 抽出されたフォルダーの名前がmongodb-win32-i386- [version]またはmongodb-win32-x86_64- [version]であることを確認してください。 ここで、[バージョン]はMongoDBダウンロードのバージョンです。

次に、コマンドプロンプトを開き、次のコマンドを実行します。

C:\>move mongodb-win64-* mongodb
   1 dir(s) moved.
C:\>

別の場所でMongoDBを抽出した場合は、コマンド cd FOOLDER/DIR を使用してそのパスに移動し、上記のプロセスを実行します。

MongoDBには、ファイルを保存するためのデータフォルダーが必要です。 MongoDBデータディレクトリのデフォルトの場所はc:\ data \ dbです。 そのため、コマンドプロンプトを使用してこのフォルダーを作成する必要があります。 次のコマンドシーケンスを実行します。

C:\>md data
C:\md data\db

MongoDBを別の場所にインストールする必要がある場合は、 mongod.exe でパス dbpath を設定して、 \ data \ db の代替パスを指定する必要があります。 同じために、次のコマンドを発行します。

コマンドプロンプトで、MongoDBインストールフォルダーにあるbinディレクトリに移動します。 私のインストールフォルダが D:\ set up \ mongodb であるとします

C:\Users\XYZ>d:
D:\>cd "set up"
D:\set up>cd mongodb
D:\set up\mongodb>cd bin
D:\set up\mongodb\bin>mongod.exe --dbpath "d:\set up\mongodb\data"

これにより、コンソール出力に waiting for connections メッセージが表示され、mongod.exeプロセスが正常に実行されていることが示されます。

ここで、MongoDBを実行するには、別のコマンドプロンプトを開き、次のコマンドを発行する必要があります。

D:\set up\mongodb\bin>mongo.exe
MongoDB shell version: 2.4.6
connecting to: test
>db.test.save( { a: 1 } )
>db.test.find()
{ "_id" : ObjectId(5879b0f65a56a454), "a" : 1 }
>

これにより、MongoDBがインストールされ、正常に実行されることが示されます。 次回MongoDBを実行するときは、コマンドのみを発行する必要があります。

D:\set up\mongodb\bin>mongod.exe --dbpath "d:\set up\mongodb\data"
D:\set up\mongodb\bin>mongo.exe

UbuntuにMongoDBをインストールする

MongoDB公開GPGキーをインポートするには、次のコマンドを実行します-

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10

次のコマンドを使用して/etc/apt/sources.list.d/mongodb.listファイルを作成します。

echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen'
   | sudo tee/etc/apt/sources.list.d/mongodb.list

リポジトリを更新するには、次のコマンドを発行します-

sudo apt-get update

次に、次のコマンドを使用してMongoDBをインストールします-

apt-get install mongodb-10gen = 2.2.3

上記のインストールでは、2.2.3が現在リリースされているMongoDBバージョンです。 常に最新バージョンをインストールしてください。 これで、MongoDBが正常にインストールされました。

MongoDBを起動します

sudo service mongodb start

MongoDBを停止します

sudo service mongodb stop

MongoDBを再起動します

sudo service mongodb restart

MongoDBを使用するには、次のコマンドを実行します。

mongo

これにより、実行中のMongoDBインスタンスに接続されます。

MongoDBヘルプ

コマンドのリストを取得するには、MongoDBクライアントで* db.help()*と入力します。 これにより、次のスクリーンショットに示すようにコマンドのリストが表示されます。

DBヘルプ

MongoDB統計

MongoDBサーバーに関する統計を取得するには、MongoDBクライアントでコマンド* db.stats()*を入力します。 これにより、データベース名、データベース内のコレクションおよびドキュメントの数が表示されます。 コマンドの出力を次のスクリーンショットに示します。

DB Stats

MongoDB-データモデリング

MongoDBのデータには、同じコレクション内の柔軟なschema.documentsがあります。 コレクションのドキュメント内の共通フィールドは、同じフィールドセットや構造を持つ必要はありません。異なるタイプのデータを保持できます。

データモデルの設計

MongoDBは、2種類のデータモデルを提供します。—埋め込みデータモデルと正規化データモデル。 要件に基づいて、ドキュメントの準備中にどちらのモデルも使用できます。

埋め込みデータモデル

このモデルでは、1つのドキュメントにすべての関連データを含める(埋め込む)ことができます。これは、非正規化データモデルとも呼ばれます。

たとえば、Personal_details、Contact、Addressの3つの異なるドキュメントで従業員の詳細を取得していると仮定すると、以下に示すように、3つのドキュメントすべてを1つのドキュメントに埋め込むことができます-

{
    _id: ,
    Emp_ID: "10025AE336"
    Personal_details:{
        First_Name: "Radhika",
        Last_Name: "Sharma",
        Date_Of_Birth: "1995-09-26"
    },
    Contact: {
        e-mail: "[email protected]",
        phone: "9848022338"
    },
    Address: {
        city: "Hyderabad",
        Area: "Madapur",
        State: "Telangana"
    }
}

正規化されたデータモデル

このモデルでは、参照を使用して、元のドキュメントのサブドキュメントを参照できます。 たとえば、上記のドキュメントを正規化モデルで次のように書き直すことができます。

社員:

{
    _id: <ObjectId101>,
    Emp_ID: "10025AE336"
}
  • Personal_details:*
{
    _id: <ObjectId102>,
    empDocID: " ObjectId101",
    First_Name: "Radhika",
    Last_Name: "Sharma",
    Date_Of_Birth: "1995-09-26"
}

接触:

{
    _id: <ObjectId103>,
    empDocID: " ObjectId101",
    e-mail: "[email protected]",
    phone: "9848022338"
}

住所:

{
    _id: <ObjectId104>,
    empDocID: " ObjectId101",
    city: "Hyderabad",
    Area: "Madapur",
    State: "Telangana"
}

MongoDBでスキーマを設計する際の考慮事項

  • ユーザー要件に従ってスキーマを設計します。
  • 一緒に使用する場合は、オブジェクトを1つのドキュメントに結合します。 それ以外の場合は分離します(ただし、結合の必要がないことを確認してください)。
  • 計算時間と比較してディスク容量が安いため、データを複製します(ただし、制限があります)。
  • 読み取り時ではなく、書き込み時に結合します。
  • 最も頻繁に使用されるケースに合わせてスキーマを最適化します。
  • スキーマで複雑な集計を行います。

クライアントが彼のブログ/ウェブサイトのデータベース設計を必要とし、RDBMSとMongoDBスキーマ設計の違いを確認するとします。 ウェブサイトには次の要件があります。

  • すべての投稿には、一意のタイトル、説明、およびURLがあります。
  • すべての投稿に1つ以上のタグを含めることができます。
  • すべての投稿には、発行者の名前といいねの総数があります。
  • すべての投稿には、ユーザーからのコメント、名前、メッセージ、日時、いいね!があります。
  • 各投稿には、0個以上のコメントを含めることができます。

RDBMSスキーマでは、上記の要件の設計に最低3つのテーブルが含まれます。

RDBMSスキーマ設計

MongoDBスキーマでは、デザインには1つのコレクションポストと次の構造があります-

{
   _id: POST_ID
   title: TITLE_OF_POST,
   description: POST_DESCRIPTION,
   by: POST_BY,
   url: URL_OF_POST,
   tags: [TAG1, TAG2, TAG3],
   likes: TOTAL_LIKES,
   comments: [
      {
         user:'COMMENT_BY',
         message: TEXT,
         dateCreated: DATE_TIME,
         like: LIKES
      },
      {
         user:'COMMENT_BY',
         message: TEXT,
         dateCreated: DATE_TIME,
         like: LIKES
      }
   ]
}

したがって、データを表示している間、RDBMSでは3つのテーブルを結合する必要があり、MongoDBでは、データは1つのコレクションからのみ表示されます。

MongoDB-データベースの作成

この章では、MongoDBでデータベースを作成する方法を説明します。

useコマンド

MongoDB use DATABASE_NAME は、データベースの作成に使用されます。 このコマンドは、存在しない場合は新しいデータベースを作成し、存在しない場合は既存のデータベースを返します。

構文

*use DATABASE* ステートメントの基本構文は次のとおりです-
use DATABASE_NAME

あなたが名前 <mydb> でデータベースを使用したい場合、 use DATABASE ステートメントは次のようになります-

>use mydb
switched to db mydb

現在選択されているデータベースを確認するには、コマンド db を使用します

>db
mydb

データベースリストを確認する場合は、 show dbs コマンドを使用します。

>show dbs
local     0.78125GB
test      0.23012GB

作成したデータベース(mydb)はリストにありません。 データベースを表示するには、少なくとも1つのドキュメントをデータベースに挿入する必要があります。

>db.movie.insert({"name":"tutorials point"})
>show dbs
local      0.78125GB
mydb       0.23012GB
test       0.23012GB

MongoDBでは、デフォルトのデータベースはtestです。 データベースを作成しなかった場合、コレクションはテストデータベースに保存されます。

MongoDB-データベースの削除

この章では、MongoDBコマンドを使用してデータベースを削除する方法を説明します。

dropDatabase()メソッド

MongoDB * db.dropDatabase()*コマンドは、既存のデータベースを削除するために使用されます。

構文

  • dropDatabase()*コマンドの基本的な構文は次のとおりです-
db.dropDatabase()

これにより、選択したデータベースが削除されます。 データベースを選択していない場合、デフォルトの「テスト」データベースが削除されます。

まず、 show dbs コマンドを使用して、使用可能なデータベースのリストを確認します。

>show dbs
local      0.78125GB
mydb       0.23012GB
test       0.23012GB
>

新しいデータベース <mydb> を削除する場合、* dropDatabase()*コマンドは次のようになります-

>use mydb
switched to db mydb
>db.dropDatabase()
>{ "dropped" : "mydb", "ok" : 1 }
>

次に、データベースのリストを確認します。

>show dbs
local      0.78125GB
test       0.23012GB
>

MongoDB-コレクションの作成

この章では、MongoDBを使用してコレクションを作成する方法を説明します。

createCollection()メソッド

MongoDB * db.createCollection(name、options)*は、コレクションの作成に使用されます。

構文

  • createCollection()*コマンドの基本的な構文は次のとおりです-
db.createCollection(name, options)

コマンドで、 name は作成するコレクションの名前です。 Options はドキュメントであり、コレクションの構成を指定するために使用されます。

Parameter Type Description
Name String Name of the collection to be created
Options Document (Optional) Specify options about memory size and indexing

optionsパラメーターはオプションであるため、コレクションの名前のみを指定する必要があります。 以下は、使用できるオプションのリストです-

Field Type Description
capped Boolean (Optional) If true, enables a capped collection. Capped collection is a fixed size collection that automatically overwrites its oldest entries when it reaches its maximum size. *If you specify true, you need to specify size parameter also. *
autoIndexId Boolean (Optional) If true, automatically create index on _id field.s Default value is false.
size number (Optional) Specifies a maximum size in bytes for a capped collection.* If capped is true, then you need to specify this field also.*
max number (Optional) Specifies the maximum number of documents allowed in the capped collection.

ドキュメントを挿入する際、MongoDBは最初に上限付きコレクションのサイズフィールドをチェックし、次に最大フィールドをチェックします。

オプションのない* createCollection()*メソッドの基本構文は次のとおりです-

>use test
switched to db test
>db.createCollection("mycollection")
{ "ok" : 1 }
>

コマンド show collections を使用して、作成されたコレクションを確認できます。

>show collections
mycollection
system.indexes

次の例は、いくつかの重要なオプションを持つ* createCollection()*メソッドの構文を示しています-

>db.createCollection("mycol", { capped : true, autoIndexId : true, size :
   6142800, max : 10000 } )
{ "ok" : 1 }
>

MongoDBでは、コレクションを作成する必要はありません。 MongoDBは、ドキュメントを挿入するとコレクションを自動的に作成します。

>db.finddevguides.insert({"name" : "finddevguides"})
>show collections
mycol
mycollection
system.indexes
finddevguides
>

MongoDB-ドロップコレクション

この章では、MongoDBを使用してコレクションを削除する方法を説明します。

drop()メソッド

MongoDBの* db.collection.drop()*は、データベースからコレクションを削除するために使用されます。

構文

  • drop()*コマンドの基本的な構文は次のとおりです-
db.COLLECTION_NAME.drop()

まず、使用可能なコレクションをデータベース mydb にチェックインします。

>use mydb
switched to db mydb
>show collections
mycol
mycollection
system.indexes
finddevguides
>

ここで、 mycollection という名前のコレクションを削除します。

>db.mycollection.drop()
true
>

再びコレクションのリストをデータベースにチェックインします。

>show collections
mycol
system.indexes
finddevguides
>

選択したコレクションが正常にドロップされた場合、drop()メソッドはtrueを返します。それ以外の場合はfalseを返します。

MongoDB-データ型

MongoDBは多くのデータ型をサポートしています。 それらのいくつかは-

  • String -これは、データを保存するために最も一般的に使用されるデータ型です。 MongoDBの文字列は有効なUTF-8でなければなりません。
  • 整数-このタイプは、数値を格納するために使用されます。 整数は、サーバーに応じて32ビットまたは64ビットになります。
  • ブール-このタイプは、ブール値(true/false)を格納するために使用されます。
  • Double -この型は、浮動小数点値を格納するために使用されます。
  • 最小/最大キー-このタイプは、値を最低および最高のBSON要素と比較するために使用されます。
  • 配列-このタイプは、配列またはリストまたは複数の値を1つのキーに格納するために使用されます。
  • タイムスタンプ-ctimestamp。 これは、ドキュメントが変更または追加されたときに記録するのに便利です。
  • オブジェクト-このデータ型は埋め込みドキュメントに使用されます。
  • Null -このタイプは、Null値を格納するために使用されます。
  • 記号-このデータ型は文字列と同じように使用されます。ただし、通常は特定のシンボルタイプを使用する言語用に予約されています。
  • 日付-このデータ型は、現在の日付または時刻をUNIX時間形式で保存するために使用されます。 Dateのオブジェクトを作成し、それに日付、月、年を渡すことにより、独自の日付時刻を指定できます。
  • *オブジェクトID *-このデータ型は、ドキュメントのIDを保存するために使用されます。
  • バイナリデータ-このデータ型はバイナリデータを保存するために使用されます。
  • コード-このデータ型は、JavaScriptコードをドキュメントに保存するために使用されます。
  • 正規表現-このデータ型は、正規表現を格納するために使用されます。

MongoDB-文書の挿入

この章では、MongoDBコレクションにドキュメントを挿入する方法を学びます。

insert()メソッド

MongoDBコレクションにデータを挿入するには、MongoDBの* insert()または save()*メソッドを使用する必要があります。

構文

  • 挿入()*コマンドの基本的な構文は次のとおりです-
>db.COLLECTION_NAME.insert(document)

> db.users.insert({
... _id : ObjectId("507f191e810c19729de860ea"),
... title: "MongoDB Overview",
... description: "MongoDB is no sql database",
... by: "tutorials point",
... url: "http://www.finddevguides.com",
... tags: ['mongodb', 'database', 'NoSQL'],
... likes: 100
... })
WriteResult({ "nInserted" : 1 })
>

ここで、 mycol は、前の章で作成したコレクション名です。 データベースにコレクションが存在しない場合、MongoDBはこのコレクションを作成し、ドキュメントを挿入します。

挿入されたドキュメントで、_idパラメーターを指定しない場合、MongoDBはこのドキュメントに一意のObjectIdを割り当てます。

_idは、コレクション内のすべてのドキュメントに固有の12バイトの16進数です。 12バイトは次のように分割されます-

_id: ObjectId(4 bytes timestamp, 3 bytes machine id, 2 bytes process id, 3 bytes incrementer)

次に示すように、ドキュメントの配列をinsert()メソッドに渡すこともできます。

> db.createCollection("post")
> db.post.insert([
    {
        title: "MongoDB Overview",
        description: "MongoDB is no SQL database",
        by: "tutorials point",
        url: "http://www.finddevguides.com",
        tags: ["mongodb", "database", "NoSQL"],
        likes: 100
    },
    {
    title: "NoSQL Database",
    description: "NoSQL database doesn't have tables",
    by: "tutorials point",
    url: "http://www.finddevguides.com",
    tags: ["mongodb", "database", "NoSQL"],
    likes: 20,
    comments: [
        {
            user:"user1",
            message: "My first comment",
            dateCreated: new Date(2013,11,10,2,35),
            like: 0
        }
    ]
}
])
BulkWriteResult({
    "writeErrors" : [ ],
    "writeConcernErrors" : [ ],
    "nInserted" : 2,
    "nUpserted" : 0,
    "nMatched" : 0,
    "nModified" : 0,
    "nRemoved" : 0,
    "upserted" : [ ]
})
>

ドキュメントを挿入するには、* db.post.save(document)も使用できます。 ドキュメントで *_id を指定しない場合、* save()メソッドは insert()*メソッドと同じように機能します。 _idを指定すると、save()メソッドで指定された_idを含むドキュメントのデータ全体が置き換えられます。

insertOne()メソッド

コレクションにドキュメントを1つだけ挿入する必要がある場合は、このメソッドを使用できます。

構文

insert()コマンドの基本的な構文は次のとおりです-

>db.COLLECTION_NAME.insertOne(document)

次の例では、empDetailsという名前の新しいコレクションを作成し、insertOne()メソッドを使用してドキュメントを挿入します。

> db.createCollection("empDetails")
{ "ok" : 1 }
> db.empDetails.insertOne(
    {
        First_Name: "Radhika",
        Last_Name: "Sharma",
        Date_Of_Birth: "1995-09-26",
        e_mail: "[email protected]",
        phone: "9848022338"
    })
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5dd62b4070fb13eec3963bea")
}
>

insertMany()メソッド

insertMany()メソッドを使用して複数のドキュメントを挿入できます。 このメソッドには、ドキュメントの配列を渡す必要があります。

次の例では、insertMany()メソッドを使用して、3つの異なるドキュメントをempDetailsコレクションに挿入します。

> db.empDetails.insertMany(
    [
        {
            First_Name: "Radhika",
            Last_Name: "Sharma",
            Date_Of_Birth: "1995-09-26",
            e_mail: "[email protected]",
            phone: "9000012345"
        },
        {
            First_Name: "Rachel",
            Last_Name: "Christopher",
            Date_Of_Birth: "1990-02-16",
            e_mail: "[email protected]",
            phone: "9000054321"
        },
        {
            First_Name: "Fathima",
            Last_Name: "Sheik",
            Date_Of_Birth: "1990-02-16",
            e_mail: "[email protected]",
            phone: "9000054321"
        }
    ]
)
{
    "acknowledged" : true,
    "insertedIds" : [
        ObjectId("5dd631f270fb13eec3963bed"),
        ObjectId("5dd631f270fb13eec3963bee"),
        ObjectId("5dd631f270fb13eec3963bef")
    ]
}
>

MongoDB-クエリドキュメント

この章では、MongoDBコレクションからドキュメントをクエリする方法を学びます。

find()メソッド

MongoDBコレクションからデータをクエリするには、MongoDBの* find()*メソッドを使用する必要があります。

構文

  • find()*メソッドの基本的な構文は次のとおりです-
>db.COLLECTION_NAME.find()
  • find()*メソッドは、構造化されていない方法ですべてのドキュメントを表示します。

mycolという名前のコレクションを作成したと仮定します-

> use sampleDB
switched to db sampleDB
> db.createCollection("mycol")
{ "ok" : 1 }
>

そして、以下に示すようにinsert()メソッドを使用してそれに3つのドキュメントを挿入しました-

> db.mycol.insert([
    {
        title: "MongoDB Overview",
        description: "MongoDB is no SQL database",
        by: "tutorials point",
        url: "http://www.finddevguides.com",
        tags: ["mongodb", "database", "NoSQL"],
        likes: 100
    },
    {
        title: "NoSQL Database",
        description: "NoSQL database doesn't have tables",
        by: "tutorials point",
        url: "http://www.finddevguides.com",
        tags: ["mongodb", "database", "NoSQL"],
        likes: 20,
        comments: [
            {
                user:"user1",
                message: "My first comment",
                dateCreated: new Date(2013,11,10,2,35),
                like: 0
            }
        ]
    }
])

次のメソッドは、コレクション内のすべてのドキュメントを取得します-

> db.mycol.find()
{ "_id" : ObjectId("5dd4e2cc0821d3b44607534c"), "title" : "MongoDB Overview", "description" : "MongoDB is no SQL database", "by" : "tutorials point", "url" : "http://www.finddevguides.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
{ "_id" : ObjectId("5dd4e2cc0821d3b44607534d"), "title" : "NoSQL Database", "description" : "NoSQL database doesn't have tables", "by" : "tutorials point", "url" : "http://www.finddevguides.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 20, "comments" : [ { "user" : "user1", "message" : "My first comment", "dateCreated" : ISODate("2013-12-09T21:05:00Z"), "like" : 0 } ] }
>

pretty()メソッド

フォーマットされた方法で結果を表示するには、pretty()メソッドを使用できます。

構文

>db.COLLECTION_NAME.find().pretty()

次の例では、mycolという名前のコレクションからすべてのドキュメントを取得し、読みやすい形式に配置しています。

> db.mycol.find().pretty()
{
    "_id" : ObjectId("5dd4e2cc0821d3b44607534c"),
    "title" : "MongoDB Overview",
    "description" : "MongoDB is no SQL database",
    "by" : "tutorials point",
    "url" : "http://www.finddevguides.com",
    "tags" : [
        "mongodb",
        "database",
        "NoSQL"
    ],
    "likes" : 100
}
{
    "_id" : ObjectId("5dd4e2cc0821d3b44607534d"),
    "title" : "NoSQL Database",
    "description" : "NoSQL database doesn't have tables",
    "by" : "tutorials point",
    "url" : "http://www.finddevguides.com",
    "tags" : [
        "mongodb",
        "database",
        "NoSQL"
    ],
    "likes" : 20,
    "comments" : [
        {
            "user" : "user1",
            "message" : "My first comment",
            "dateCreated" : ISODate("2013-12-09T21:05:00Z"),
            "like" : 0
        }
    ]
}

findOne()メソッド

find()メソッドとは別に、1つのドキュメントのみを返す* findOne()*メソッドがあります。

構文

>db.COLLECTIONNAME.findOne()

次の例では、MongoDB Overviewというタイトルのドキュメントを取得します。

> db.mycol.findOne({title: "MongoDB Overview"})
{
    "_id" : ObjectId("5dd6542170fb13eec3963bf0"),
    "title" : "MongoDB Overview",
    "description" : "MongoDB is no SQL database",
    "by" : "tutorials point",
    "url" : "http://www.finddevguides.com",
    "tags" : [
        "mongodb",
        "database",
        "NoSQL"
    ],
    "likes" : 100
}

MongoDBでのRDBMS Where句の同等物

何らかの条件に基づいてドキュメントを照会するには、次の操作を使用できます。

Operation Syntax Example RDBMS Equivalent
Equality \{<key>:\{$eg;<value>}} db.mycol.find(\{"by":"tutorials point"}).pretty() where by = 'tutorials point'
Less Than \{<key>:\{$lt:<value>}} db.mycol.find(\{"likes":\{$lt:50}}).pretty() where likes < 50
Less Than Equals \{<key>:\{$lte:<value>}} db.mycol.find(\{"likes":\{$lte:50}}).pretty() where likes ⇐ 50
Greater Than \{<key>:\{$gt:<value>}} db.mycol.find(\{"likes":\{$gt:50}}).pretty() where likes > 50
Greater Than Equals \{<key>:\{$gte:<value>}} db.mycol.find(\{"likes":\{$gte:50}}).pretty() where likes >= 50
Not Equals \{<key>:\{$ne:<value>}} db.mycol.find(\{"likes":\{$ne:50}}).pretty() where likes != 50
Values in an array \{<key>:\{$in:[<value1>, <value2>,……<valueN>]}} db.mycol.find(\{"name":\{$in:["Raj", "Ram", "Raghu"]}}).pretty() Where name matches any of the value in :["Raj", "Ram", "Raghu"]
Values not in an array \{<key>:\{$nin:<value>}} db.mycol.find(\{"name":\{$nin:["Ramu", "Raghav"]}}).pretty() Where name values is not in the array :["Ramu", "Raghav"] or, doesn’t exist at all

およびMongoDB内

構文

AND条件に基づいてドキュメントをクエリするには、$ andキーワードを使用する必要があります。 以下は、ANDの基本的な構文です-

>db.mycol.find({ $and: [ {<key1>:<value1>}, { <key2>:<value2>} ] })

次の例は、「チュートリアルポイント」で作成され、タイトルが「MongoDB Overview」であるすべてのチュートリアルを示します。

> db.mycol.find({$and:[{"by":"tutorials point"},{"title": "MongoDB Overview"}]}).pretty()
{
    "_id" : ObjectId("5dd4e2cc0821d3b44607534c"),
    "title" : "MongoDB Overview",
    "description" : "MongoDB is no SQL database",
    "by" : "tutorials point",
    "url" : "http://www.finddevguides.com",
    "tags" : [
        "mongodb",
        "database",
        "NoSQL"
    ],
    "likes" : 100
}
>

上記の例では、同等のwhere句は 'where by =' tutorials point 'AND title =' MongoDB Overview になります。 find句では、キーと値のペアをいくつでも渡すことができます。

またはMongoDBで

構文

OR条件に基づいてドキュメントをクエリするには、 $ or キーワードを使用する必要があります。 以下は OR の基本的な構文です-

>db.mycol.find(
   {
      $or: [
         {key1: value1}, {key2:value2}
      ]
   }
).pretty()

次の例は、「チュートリアルポイント」またはタイトルが「MongoDB Overview」で書かれたすべてのチュートリアルを示します。

>db.mycol.find({$or:[{"by":"tutorials point"},{"title": "MongoDB Overview"}]}).pretty()
{
   "_id": ObjectId(7df78ad8902c),
   "title": "MongoDB Overview",
   "description": "MongoDB is no sql database",
   "by": "tutorials point",
   "url": "http://www.finddevguides.com",
   "tags": ["mongodb", "database", "NoSQL"],
   "likes": "100"
}
>

ANDとORを一緒に使用する

次の例は、10以上のいいね!を持ち、タイトルが「MongoDB Overview」またはbyが「tutorials point」であるドキュメントを示します。 同等のSQL where句は 'where likes> 10 AND(by =' tutorials point 'OR title =' MongoDB Overview ')'

>db.mycol.find({"likes": {$gt:10}, $or: [{"by": "tutorials point"},
   {"title": "MongoDB Overview"}]}).pretty()
{
   "_id": ObjectId(7df78ad8902c),
   "title": "MongoDB Overview",
   "description": "MongoDB is no sql database",
   "by": "tutorials point",
   "url": "http://www.finddevguides.com",
   "tags": ["mongodb", "database", "NoSQL"],
   "likes": "100"
}
>

MongoDBのNOR

構文

NOT条件に基づいてドキュメントをクエリするには、$ notキーワードを使用する必要があります。 以下は NOT の基本構文です-

>db.COLLECTION_NAME.find(
    {
        $not: [
            {key1: value1}, {key2:value2}
        ]
    }
)

以下に示すように、コレクション empDetails に3つのドキュメントを挿入したと仮定します-

db.empDetails.insertMany(
    [
        {
            First_Name: "Radhika",
            Last_Name: "Sharma",
            Age: "26",
            e_mail: "[email protected]",
            phone: "9000012345"
        },
        {
            First_Name: "Rachel",
            Last_Name: "Christopher",
            Age: "27",
            e_mail: "[email protected]",
            phone: "9000054321"
        },
        {
            First_Name: "Fathima",
            Last_Name: "Sheik",
            Age: "24",
            e_mail: "[email protected]",
            phone: "9000054321"
        }
    ]
)

次の例では、名が「Radhika」ではなく、姓が「Christopher」ではないドキュメントを取得します。

> db.empDetails.find(
    {
        $nor:[
            40
            {"First_Name": "Radhika"},
            {"Last_Name": "Christopher"}
        ]
    }
).pretty()
{
    "_id" : ObjectId("5dd631f270fb13eec3963bef"),
    "First_Name" : "Fathima",
    "Last_Name" : "Sheik",
    "Age" : "24",
    "e_mail" : "[email protected]",
    "phone" : "9000054321"
}

MongoDBにはない

構文

NOT条件に基づいてドキュメントをクエリするには、$ NOTキーワードを使用する必要があります。以下は NOT の基本構文です-

>db.COLLECTION_NAME.find(
    {
        $NOT: [
            {key1: value1}, {key2:value2}
        ]
    }
).pretty()

次の例では、年齢が25以下のドキュメントを取得します

> db.empDetails.find( { "Age": { $not: { $gt: "25" } } } )
{
    "_id" : ObjectId("5dd6636870fb13eec3963bf7"),
    "First_Name" : "Fathima",
    "Last_Name" : "Sheik",
    "Age" : "24",
    "e_mail" : "[email protected]",
    "phone" : "9000054321"
}

MongoDB-ドキュメントの更新

MongoDBの* update()および save()*メソッドは、ドキュメントをコレクションに更新するために使用されます。 update()メソッドは既存のドキュメントの値を更新し、save()メソッドは既存のドキュメントをsave()メソッドで渡されたドキュメントに置き換えます。

MongoDB Update()メソッド

update()メソッドは、既存のドキュメントの値を更新します。

構文

  • update()*メソッドの基本的な構文は次のとおりです-
>db.COLLECTION_NAME.update(SELECTION_CRITERIA, UPDATED_DATA)

mycolコレクションには次のデータがあると考えてください。

{ "_id" : ObjectId(5983548781331adf45ec5), "title":"MongoDB Overview"}
{ "_id" : ObjectId(5983548781331adf45ec6), "title":"NoSQL Overview"}
{ "_id" : ObjectId(5983548781331adf45ec7), "title":"Tutorials Point Overview"}

次の例では、タイトルが「MongoDB Overview」であるドキュメントの新しいタイトル「New MongoDB Tutorial」を設定します。

>db.mycol.update({'title':'MongoDB Overview'},{$set:{'title':'New MongoDB Tutorial'}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
>db.mycol.find()
{ "_id" : ObjectId(5983548781331adf45ec5), "title":"New MongoDB Tutorial"}
{ "_id" : ObjectId(5983548781331adf45ec6), "title":"NoSQL Overview"}
{ "_id" : ObjectId(5983548781331adf45ec7), "title":"Tutorials Point Overview"}
>

デフォルトでは、MongoDBは1つのドキュメントのみを更新します。 複数のドキュメントを更新するには、パラメーター 'multi’をtrueに設定する必要があります。

>db.mycol.update({'title':'MongoDB Overview'},
   {$set:{'title':'New MongoDB Tutorial'}},{multi:true})

MongoDB Save()メソッド

  • save()*メソッドは、既存のドキュメントをsave()メソッドで渡された新しいドキュメントに置き換えます。

構文

MongoDB * save()*メソッドの基本的な構文を以下に示します-

>db.COLLECTION_NAME.save({_id:ObjectId(),NEW_DATA})

次の例では、ドキュメントを_id '5983548781331adf45ec5’に置き換えます。

>db.mycol.save(
   {
      "_id" : ObjectId("507f191e810c19729de860ea"),
        "title":"Tutorials Point New Topic",
      "by":"Tutorials Point"
   }
)
WriteResult({
    "nMatched" : 0,
    "nUpserted" : 1,
    "nModified" : 0,
    "_id" : ObjectId("507f191e810c19729de860ea")
})
>db.mycol.find()
{ "_id" : ObjectId("507f191e810c19729de860e6"), "title":"Tutorials Point New Topic",
   "by":"Tutorials Point"}
{ "_id" : ObjectId("507f191e810c19729de860e6"), "title":"NoSQL Overview"}
{ "_id" : ObjectId("507f191e810c19729de860e6"), "title":"Tutorials Point Overview"}
>

MongoDB findOneAndUpdate()メソッド

  • findOneAndUpdate()*メソッドは、既存のドキュメントの値を更新します。

構文

  • findOneAndUpdate()*メソッドの基本的な構文は次のとおりです-
>db.COLLECTION_NAME.findOneAndUpdate(SELECTIOIN_CRITERIA, UPDATED_DATA)

以下に示すように、empDetailsという名前のコレクションを作成し、それに3つのドキュメントを挿入したと仮定します-

> db.empDetails.insertMany(
    [
        {
            First_Name: "Radhika",
            Last_Name: "Sharma",
            Age: "26",
            e_mail: "[email protected]",
            phone: "9000012345"
        },
        {
            First_Name: "Rachel",
            Last_Name: "Christopher",
            Age: "27",
            e_mail: "[email protected]",
            phone: "9000054321"
        },
        {
            First_Name: "Fathima",
            Last_Name: "Sheik",
            Age: "24",
            e_mail: "[email protected]",
            phone: "9000054321"
        }
    ]
)

次の例では、「Radhika」という名前のドキュメントの年齢と電子メールの値を更新します。

> db.empDetails.findOneAndUpdate(
    {First_Name: 'Radhika'},
    { $set: { Age: '30',e_mail: '[email protected]'}}
)
{
    "_id" : ObjectId("5dd6636870fb13eec3963bf5"),
    "First_Name" : "Radhika",
    "Last_Name" : "Sharma",
    "Age" : "30",
    "e_mail" : "[email protected]",
    "phone" : "9000012345"
}

MongoDB updateOne()メソッド

このメソッドは、指定されたフィルターに一致する単一のドキュメントを更新します。

構文

updateOne()メソッドの基本的な構文は次のとおりです-

>db.COLLECTION_NAME.updateOne(<filter>, <update>)

> db.empDetails.updateOne(
    {First_Name: 'Radhika'},
    { $set: { Age: '30',e_mail: '[email protected]'}}
)
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 0 }
>

MongoDB updateMany()メソッド

updateMany()メソッドは、指定されたフィルターに一致するすべてのドキュメントを更新します。

構文

updateMany()メソッドの基本的な構文は次のとおりです-

>db.COLLECTION_NAME.update(<filter>, <update>)

> db.empDetails.updateMany(
    {Age:{ $gt: "25" }},
    { $set: { Age: '00'}}
)
{ "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }

以下に示すように、findメソッドを使用してドキュメントのコンテンツを取得すると、更新された値を確認できます-

> db.empDetails.find()
{ "_id" : ObjectId("5dd6636870fb13eec3963bf5"), "First_Name" : "Radhika", "Last_Name" : "Sharma", "Age" : "00", "e_mail" : "[email protected]", "phone" : "9000012345" }
{ "_id" : ObjectId("5dd6636870fb13eec3963bf6"), "First_Name" : "Rachel", "Last_Name" : "Christopher", "Age" : "00", "e_mail" : "[email protected]", "phone" : "9000054321" }
{ "_id" : ObjectId("5dd6636870fb13eec3963bf7"), "First_Name" : "Fathima", "Last_Name" : "Sheik", "Age" : "24", "e_mail" : "[email protected]", "phone" : "9000054321" }
>

MongoDB-ドキュメントの削除

この章では、MongoDBを使用してドキュメントを削除する方法を学びます。

remove()メソッド

MongoDBの* remove()*メソッドは、コレクションからドキュメントを削除するために使用されます。 remove()メソッドは2つのパラメーターを受け入れます。 1つは削除基準で、2つ目はjustOneフラグです。

  • 削除基準-(オプション)文書による削除基準は削除されます。
  • justOne -(オプション)trueまたは1に設定されている場合、1つのドキュメントのみを削除します。

構文

  • remove()*メソッドの基本的な構文は次のとおりです-
>db.COLLECTION_NAME.remove(DELLETION_CRITTERIA)

mycolコレクションには次のデータがあると考えてください。

{_id : ObjectId("507f191e810c19729de860e1"), title: "MongoDB Overview"},
{_id : ObjectId("507f191e810c19729de860e2"), title: "NoSQL Overview"},
{_id : ObjectId("507f191e810c19729de860e3"), title: "Tutorials Point Overview"}

次の例では、タイトルが「MongoDB Overview」であるすべてのドキュメントを削除します。

>db.mycol.remove({'title':'MongoDB Overview'})
WriteResult({"nRemoved" : 1})
> db.mycol.find()
{"_id" : ObjectId("507f191e810c19729de860e2"), "title" : "NoSQL Overview" }
{"_id" : ObjectId("507f191e810c19729de860e3"), "title" : "Tutorials Point Overview" }

1つのみを削除

複数のレコードがあり、最初のレコードのみを削除する場合は、* remove()メソッドで *justOne パラメーターを設定します。

>db.COLLECTION_NAME.remove(DELETION_CRITERIA,1)

すべてのドキュメントを削除

削除条件を指定しない場合、MongoDBはコレクションからドキュメント全体を削除します。 これは、SQLのtruncateコマンドと同等です。

> db.mycol.remove({})
WriteResult({ "nRemoved" : 2 })
> db.mycol.find()
>

MongoDB-プロジェクション

MongoDBでは、投影とは、ドキュメントのデータ全体を選択するのではなく、必要なデータのみを選択することです。 文書に5つのフィールドがあり、3つだけ表示する必要がある場合は、それらから3つのフィールドのみを選択します。

find()メソッド

link:/mongodb/mongodb_query_document [MongoDB Query Document]で説明されているMongoDBの* find()メソッドは、取得するフィールドのリストである2番目のオプションパラメータを受け入れます。 MongoDBでは、 find()*メソッドを実行すると、ドキュメントのすべてのフィールドが表示されます。 これを制限するには、フィールドのリストに値1または0を設定する必要があります。 1はフィールドを表示するために使用され、0はフィールドを非表示にするために使用されます。

構文

投影と* find()*メソッドの基本的な構文は次のとおりです-

>db.COLLECTION_NAME.find({},{KEY:1})

コレクションmycolが次のデータを持っていると考えてください-

{_id : ObjectId("507f191e810c19729de860e1"), title: "MongoDB Overview"},
{_id : ObjectId("507f191e810c19729de860e2"), title: "NoSQL Overview"},
{_id : ObjectId("507f191e810c19729de860e3"), title: "Tutorials Point Overview"}

次の例では、ドキュメントのクエリ中にドキュメントのタイトルが表示されます。

>db.mycol.find({},{"title":1,_id:0})
{"title":"MongoDB Overview"}
{"title":"NoSQL Overview"}
{"title":"Tutorials Point Overview"}
>
  • find()メソッドの実行中は常に *_id フィールドが表示されることに注意してください。このフィールドが必要ない場合は、0に設定する必要があります。

MongoDB-レコードの制限

この章では、MongoDBを使用してレコードを制限する方法を学習します。

Limit()メソッド

MongoDBのレコードを制限するには、* limit()*メソッドを使用する必要があります。 このメソッドは、表示するドキュメントの数である1つの数値型引数を受け入れます。

構文

  • limit()*メソッドの基本的な構文は次のとおりです-
>db.COLLECTION_NAME.find().limit(NUMBER)

コレクションmyycolには次のデータがあると考えてください。

{_id : ObjectId("507f191e810c19729de860e1"), title: "MongoDB Overview"},
{_id : ObjectId("507f191e810c19729de860e2"), title: "NoSQL Overview"},
{_id : ObjectId("507f191e810c19729de860e3"), title: "Tutorials Point Overview"}

次の例では、ドキュメントのクエリ中に2つのドキュメントのみが表示されます。

>db.mycol.find({},{"title":1,_id:0}).limit(2)
{"title":"MongoDB Overview"}
{"title":"NoSQL Overview"}
>
  • limit()*メソッドでnumber引数を指定しない場合、コレクションのすべてのドキュメントが表示されます。

MongoDB Skip()メソッド

limit()メソッドとは別に、もう1つのメソッド* skip()*があります。これは、数値型の引数も受け入れ、ドキュメントの数をスキップするために使用されます。

構文

  • skip()*メソッドの基本的な構文は次のとおりです-
>db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)

次の例では、2番目のドキュメントのみが表示されます。

>db.mycol.find({},{"title":1,_id:0}).limit(1).skip(1)
{"title":"NoSQL Overview"}
>
  • skip()*メソッドのデフォルト値は0であることに注意してください。

MongoDB-レコードの並べ替え

この章では、MongoDBでレコードをソートする方法を学びます。

sort()メソッド

MongoDBでドキュメントをソートするには、* sort()*メソッドを使用する必要があります。 このメソッドは、フィールドのリストとそのソート順を含むドキュメントを受け入れます。 ソート順を指定するには、1と-1が使用されます。 1は昇順で使用され、-1は降順で使用されます。

構文

  • sort()*メソッドの基本的な構文は次のとおりです-
>db.COLLECTION_NAME.find().sort({KEY:1})

コレクションmyycolには次のデータがあると考えてください。

{_id : ObjectId("507f191e810c19729de860e1"), title: "MongoDB Overview"}
{_id : ObjectId("507f191e810c19729de860e2"), title: "NoSQL Overview"}
{_id : ObjectId("507f191e810c19729de860e3"), title: "Tutorials Point Overview"}

次の例では、ドキュメントをタイトルで降順で並べ替えて表示します。

>db.mycol.find({},{"title":1,_id:0}).sort({"title":-1})
{"title":"Tutorials Point Overview"}
{"title":"NoSQL Overview"}
{"title":"MongoDB Overview"}
>

ソート設定を指定しない場合、* sort()*メソッドはドキュメントを昇順で表示することに注意してください。

MongoDB-インデックス作成

インデックスは、クエリの効率的な解決をサポートします。 インデックスがない場合、MongoDBはコレクションのすべてのドキュメントをスキャンして、クエリステートメントに一致するドキュメントを選択する必要があります。 このスキャンは非常に非効率的であり、MongoDBが大量のデータを処理する必要があります。

インデックスは特別なデータ構造で、データセットのごく一部を走査しやすい形式で保存します。 インデックスは、特定のフィールドまたはフィールドのセットの値を、インデックスで指定されたフィールドの値の順に格納します。

createIndex()メソッド

インデックスを作成するには、MongoDBのcreateIndex()メソッドを使用する必要があります。

構文

  • createIndex()*メソッドの基本的な構文は、次のとおりです()。
>db.COLLECTION_NAME.createIndex({KEY:1})

ここで、キーはインデックスを作成するフィールドの名前で、1は昇順です。 降順でインデックスを作成するには、-1を使用する必要があります。

>db.mycol.createIndex({"title":1})
{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}
>
  • createIndex()*メソッドでは、複数のフィールドを渡して、複数のフィールドにインデックスを作成できます。
>db.mycol.createIndex({"title":1,"description":-1})
>

このメソッドは、オプションのリストも受け入れます(オプション)。 以下はリストです-

パラメータ

Type

説明

バックグラウンド

ブール値

インデックスを作成しても他のデータベースアクティビティがブロックされないように、インデックスをバックグラウンドで作成します。 バックグラウンドでビルドするには、trueを指定します。 デフォルト値は false です。

独特の

ブール値

一意のインデックスを作成して、コレクションが、インデックスキーがインデックス内の既存の値と一致するドキュメントの挿入を受け入れないようにします。 一意のインデックスを作成するには、trueを指定します。 デフォルト値は false です。

name

ひも

インデックスの名前。 指定しない場合、MongoDBはインデックス付きフィールドの名前とソート順を連結してインデックス名を生成します。

まばらな

ブール値

trueの場合、インデックスは指定されたフィールドを持つドキュメントのみを参照します。 これらのインデックスは使用するスペースが少なくなりますが、状況によっては動作が異なります(特にソート)。 デフォルト値は false です。

expireAfterSeconds

整数

MongoDBがこのコレクション内のドキュメントを保持する期間を制御するTTLとして値を秒単位で指定します。

重み

資料

重みは1から99,999の範囲の数値であり、スコアに関して他のインデックス付きフィールドに対するフィールドの重要度を示します。

既定の言語

ひも

テキストインデックスの場合、ストップワードのリストを決定する言語と、ステマーおよびトークナイザーのルール。 デフォルト値は English です。

language_override

ひも

テキストインデックスの場合、デフォルトの言語を上書きする言語を含むドキュメントのフィールドの名前を指定します。 デフォルト値は言語です。

dropIndex()メソッド

MongoDBのdropIndex()メソッドを使用して、特定のインデックスを削除できます。

構文

DropIndex()メソッドの基本的な構文は次のとおりです()。

>db.COLLECTION_NAME.dropIndex({KEY:1})

ここで、keyはインデックスを作成するファイルの名前で、1は昇順です。 降順でインデックスを作成するには、-1を使用する必要があります。

> db.mycol.dropIndex({"title":1})
{
    "ok" : 0,
    "errmsg" : "can't find index with key: { title: 1.0 }",
    "code" : 27,
    "codeName" : "IndexNotFound"
}

dropIndexes()メソッド

このメソッドは、コレクションの複数の(指定された)インデックスを削除します。

構文

DropIndexes()メソッドの基本的な構文は次のとおりです()-

>db.COLLECTION_NAME.dropIndexes()

以下に示すように、名前付きのmycolコレクションに2つのインデックスを作成したと仮定します-

> db.mycol.createIndex({"title":1,"description":-1})

次の例では、上記で作成したmycolのインデックスを削除します-

>db.mycol.dropIndexes({"title":1,"description":-1})
{ "nIndexesWas" : 2, "ok" : 1 }
>

getIndexes()メソッド

このメソッドは、コレクション内のすべてのインデックスの説明を返します。

構文

以下は、getIndexes()メソッドの基本的な構文です-

db.COLLECTION_NAME.getIndexes()

以下に示すように、名前付きのmycolコレクションに2つのインデックスを作成したと仮定します-

> db.mycol.createIndex({"title":1,"description":-1})

次の例は、コレクションmycolのすべてのインデックスを取得します-

> db.mycol.getIndexes()
[
    {
        "v" : 2,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "test.mycol"
    },
    {
        "v" : 2,
        "key" : {
            "title" : 1,
            "description" : -1
        },
        "name" : "title_1_description_-1",
        "ns" : "test.mycol"
    }
]
>

MongoDB-集約

集計操作はデータレコードを処理し、計算結果を返します。 集約操作は、複数のドキュメントの値をグループ化し、グループ化されたデータに対してさまざまな操作を実行して、単一の結果を返すことができます。 SQLではcount(*)とgroup byはMongoDB集計と同等です。

aggregate()メソッド

MongoDBでの集計には、* aggregate()*メソッドを使用する必要があります。

構文

  • aggregate()*メソッドの基本的な構文は次のとおりです-
>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)

コレクションには、次のデータがあります-

{
   _id: ObjectId(7df78ad8902c)
   title: 'MongoDB Overview',
   description: 'MongoDB is no sql database',
   by_user: 'tutorials point',
   url: 'http://www.finddevguides.com',
   tags: ['mongodb', 'database', 'NoSQL'],
   likes: 100
},
{
   _id: ObjectId(7df78ad8902d)
   title: 'NoSQL Overview',
   description: 'No sql database is very fast',
   by_user: 'tutorials point',
   url: 'http://www.finddevguides.com',
   tags: ['mongodb', 'database', 'NoSQL'],
   likes: 10
},
{
   _id: ObjectId(7df78ad8902e)
   title: 'Neo4j Overview',
   description: 'Neo4j is no sql database',
   by_user: 'Neo4j',
   url: 'http://www.neo4j.com',
   tags: ['neo4j', 'database', 'NoSQL'],
   likes: 750
},

今、上記のコレクションから、各ユーザーが作成したチュートリアルの数を示すリストを表示する場合は、次の* aggregate()*メソッドを使用します-

> db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
{ "_id" : "tutorials point", "num_tutorial" : 2 }
{ "_id" : "Neo4j", "num_tutorial" : 1 }
>

上記のユースケースのSQL同等のクエリは、by_user のmycol groupから select by_user、count(*)になります。

上記の例では、 by_user フィールドごとにドキュメントをグループ化し、ユーザーごとに発生するたびに、以前の値sumがインクリメントされます。 以下は利用可能な集約式のリストです。

Expression Description Example
$sum Sums up the defined value from all documents in the collection. db.mycol.aggregate([\{$group : \{_id : "$by_user", num_tutorial : \{$sum : "$likes"}}}])
$avg Calculates the average of all given values from all documents in the collection. db.mycol.aggregate([\{$group : \{_id : "$by_user", num_tutorial : \{$avg : "$likes"}}}])
$min Gets the minimum of the corresponding values from all documents in the collection. db.mycol.aggregate([\{$group : \{_id : "$by_user", num_tutorial : \{$min : "$likes"}}}])
$max Gets the maximum of the corresponding values from all documents in the collection. db.mycol.aggregate([\{$group : \{_id : "$by_user", num_tutorial : \{$max : "$likes"}}}])
$push Inserts the value to an array in the resulting document. db.mycol.aggregate([\{$group : \{_id : "$by_user", url : \{$push: "$url"}}}])
$addToSet Inserts the value to an array in the resulting document but does not create duplicates. db.mycol.aggregate([\{$group : \{_id : "$by_user", url : \{$addToSet : "$url"}}}])
$first Gets the first document from the source documents according to the grouping. Typically this makes only sense together with some previously applied “$sort”-stage. db.mycol.aggregate([\{$group : \{_id : "$by_user", first_url : \{$first : "$url"}}}])
$last Gets the last document from the source documents according to the grouping. Typically this makes only sense together with some previously applied “$sort”-stage. db.mycol.aggregate([\{$group : \{_id : "$by_user", last_url : \{$last : "$url"}}}])

パイプラインのコンセプト

UNIXコマンドでは、シェルパイプラインとは、ある入力で操作を実行し、その出力を次のコマンドの入力などとして使用する可能性を意味します。 MongoDBは、集計フレームワークでも同じ概念をサポートしています。 可能なステージのセットがあり、それらの各ステージは入力としてドキュメントのセットとして取得され、ドキュメントの結果セット(またはパイプラインの最後に最終的な結果のJSONドキュメント)を生成します。 これは、次のステージなどに順番に使用できます。

集約フレームワークで可能な段階は次のとおりです-

  • $ project -コレクションから特定のフィールドを選択するために使用されます。
  • $ match -これはフィルタリング操作であるため、次の段階への入力として与えられるドキュメントの量を減らすことができます。
  • $ group -これは上記のように実際の集約を行います。
  • $ sort -ドキュメントをソートします。
  • $ skip -これにより、一定量のドキュメントのドキュメントのリストを前方にスキップすることができます。
  • $ limit -これは、現在の位置から始まる指定された数で、見るドキュメントの量を制限します。
  • $ unwind -これは配列を使用しているドキュメントを巻き戻すために使用されます。 配列を使用する場合、データは一種の事前結合されており、この操作は元に戻され、個々のドキュメントが再び取得されます。 したがって、この段階では、次の段階のドキュメントの量を増やします。

MongoDB-レプリケーション

レプリケーションは、複数のサーバー間でデータを同期するプロセスです。 レプリケーションは冗長性を提供し、異なるデータベースサーバー上のデータの複数のコピーによりデータの可用性を高めます。 レプリケーションは、単一サーバーの損失からデータベースを保護します。 レプリケーションを使用すると、ハードウェア障害やサービスの中断から回復することもできます。 データの追加コピーを使用して、災害復旧、レポート、またはバックアップ専用にすることができます。

複製する理由

  • データを安全に保つために データの高可用性(24 7)
  • 災害からの回復
  • メンテナンスのためのダウンタイムなし(バックアップ、インデックスの再構築、圧縮など)
  • 読み取りスケーリング(読み取り元の追加コピー)
  • レプリカセットはアプリケーションに対して透過的です

MongoDBでのレプリケーションの仕組み

MongoDBは、レプリカセットを使用してレプリケーションを実現します。 レプリカセットは、同じデータセットをホストする mongod インスタンスのグループです。 レプリカでは、1つのノードがすべての書き込み操作を受け取るプライマリノードです。 セカンダリなどの他のすべてのインスタンスは、プライマリからの操作を適用して、同じデータセットを持つようにします。 レプリカセットには、プライマリノードを1つだけ含めることができます。

  • レプリカセットは、2つ以上のノードのグループです(通常、最低3つのノードが必要です)。
  • レプリカセットでは、1つのノードがプライマリノードで、残りのノードがセカンダリノードです。
  • すべてのデータは、プライマリノードからセカンダリノードに複製されます。
  • 自動フェールオーバーまたはメンテナンス時に、プライマリの選択が確立され、新しいプライマリノードが選択されます。
  • 障害が発生したノードの回復後、レプリカセットに再び参加し、セカンダリノードとして機能します。

クライアントアプリケーションが常にプライマリノードと対話し、プライマリノードがデータをセカンダリノードに複製するMongoDBレプリケーションの典型的な図を示します。

MongoDBレプリケーション

レプリカセットの機能

  • N個のノードのクラスター
  • 任意の1つのノードをプライマリにすることができます
  • すべての書き込み操作はプライマリに移動します
  • 自動フェイルオーバー
  • 自動回復
  • プライマリーのコンセンサス選挙

レプリカセットをセットアップする

このチュートリアルでは、スタンドアロンMongoDBインスタンスをレプリカセットに変換します。 レプリカセットに変換するには、次の手順があります-

  • MongoDBサーバーを実行中のシャットダウン。
  • {ブランク}
  • -replSetオプションを指定して、MongoDBサーバーを起動します。 以下は、--replSetの基本的な構文です-
mongod --port "PORT" --dbpath "YOUR_DB_DATA_PATH" --replSet "REPLICA_SET_INSTANCE_NAME"

mongod --port 27017 --dbpath "D:\set up\mongodb\data" --replSet rs0
  • ポート27017で、rs0という名前のmongodインスタンスを開始します。
  • コマンドプロンプトを起動して、このmongodインスタンスに接続します。
  • Mongoクライアントで、コマンド* rs.initiate()*を発行して、新しいレプリカセットを開始します。
  • レプリカセットの構成を確認するには、* rs.conf()コマンドを発行します。 レプリカセットのステータスを確認するには、コマンド rs.status()*を発行します。

メンバーをレプリカセットに追加する

メンバーをレプリカセットに追加するには、複数のマシンでmongodインスタンスを起動します。 次に、mongoクライアントを起動し、コマンド* rs.add()*を発行します。

構文

  • rs.add()*コマンドの基本的な構文は次のとおりです-
>rs.add(HOST_NAME:PORT)

mongodインスタンス名が mongod1.net で、ポート 27017 で実行されているとします。 このインスタンスをレプリカセットに追加するには、Mongoクライアントでコマンド* rs.add()*を発行します。

>rs.add("mongod1.net:27017")
>

プライマリノードに接続している場合にのみ、レプリカセットにmongodインスタンスを追加できます。 プライマリに接続しているかどうかを確認するには、mongoクライアントでコマンド* db.isMaster()*を発行します。

MongoDB-シャーディング

シャーディングは、複数のマシンにデータレコードを保存するプロセスであり、データ増加の要求を満たすためのMongoDBのアプローチです。 データのサイズが大きくなると、1台のマシンではデータを保存したり、読み取りおよび書き込みのスループットを許容したりするのに十分ではなくなる場合があります。 シャーディングは、水平スケーリングで問題を解決します。 シャーディングでは、データの増加と読み取りおよび書き込み操作の要求をサポートするマシンを追加します。

なぜシャーディングなのか?

  • レプリケーションでは、すべての書き込みはマスターノードに送信されます
  • 遅延に敏感なクエリはまだマスターになります
  • 単一のレプリカセットには12ノードの制限があります
  • アクティブなデータセットが大きい場合、メモリを十分に大きくすることはできません
  • ローカルディスクが十分に大きくありません
  • 垂直スケーリングは高すぎる

MongoDBのシャーディング

次の図は、分割クラスターを使用したMongoDBの分割を示しています。

MongoDBシャーディング

次の図では、3つの主要なコンポーネントがあります-

  • シャード-シャードはデータの保存に使用されます。 高可用性とデータの一貫性を提供します。 実稼働環境では、各シャードは個別のレプリカセットです。
  • 構成サーバー-構成サーバーはクラスターのメタデータを保存します。 このデータには、クラスターのデータセットとシャードのマッピングが含まれています。 クエリルーターは、このメタデータを使用して、操作のターゲットを特定のシャードにします。 実稼働環境では、シャードクラスターには正確に3つの構成サーバーがあります。
  • クエリルーター-クエリルーターは、基本的にmongoインスタンスであり、クライアントアプリケーションとのインターフェイスであり、適切なシャードへの直接操作です。 クエリルーターは、操作を処理してシャードを対象とし、結果をクライアントに返します。 シャードクラスターには、クライアント要求の負荷を分割するために複数のクエリルーターを含めることができます。 クライアントは、1つのクエリルーターに要求を送信します。 一般に、シャードクラスターには多くのクエリルーターがあります。

MongoDB-バックアップの作成

この章では、MongoDBでバックアップを作成する方法を説明します。

MongoDBデータをダンプする

MongoDBでデータベースのバックアップを作成するには、 mongodump コマンドを使用する必要があります。 このコマンドは、サーバーのデータ全体をダンプディレクトリにダンプします。 データの量を制限したり、リモートサーバーのバックアップを作成したりできる多くのオプションがあります。

構文

*mongodump* コマンドの基本的な構文は次のとおりです-
>mongodump

mongodサーバーを起動します。 mongodサーバーがlocalhostおよびポート27017で実行されていると仮定して、コマンドプロンプトを開き、mongodbインスタンスのbinディレクトリに移動して、コマンド mongodump を入力します。

mycolコレクションには次のデータがあると考えてください。

>mongodump

このコマンドは、 127.0.0.1 およびポート 27017 で実行されているサーバーに接続し、サーバーのすべてのデータをディレクトリ /bin/dump/ に戻します。 以下は、コマンドの出力です-

DB Stats

以下は、 mongodump コマンドで使用できる利用可能なオプションのリストです。

Syntax Description Example
mongodump --host HOST_NAME --port PORT_NUMBER This commmand will backup all databases of specified mongod instance. mongodump --host finddevguides.com --port 27017
mongodump --dbpath DB_PATH --out BACKUP_DIRECTORY This command will backup only specified database at specified path. mongodump --dbpath/data/db/--out/data/backup/
mongodump --collection COLLECTION --db DB_NAME This command will backup only specified collection of specified database. mongodump --collection mycol --db test

データを復元する

バックアップデータを復元するには、MongoDBの mongorestore コマンドを使用します。 このコマンドは、バックアップディレクトリからすべてのデータを復元します。

構文

*mongorestore* コマンドの基本的な構文は次のとおりです-
>mongorestore

以下は、コマンドの出力です-

DB統計

MongoDB-デプロイメント

MongoDBデプロイメントを準備するときは、アプリケーションが本番環境でどのように保持されるかを理解する必要があります。 展開環境を管理するための一貫した反復可能なアプローチを開発して、本番環境での驚きを最小限に抑えることをお勧めします。

最適なアプローチには、セットアップのプロトタイピング、負荷テストの実施、主要なメトリックの監視、およびその情報を使用したセットアップのスケーリングが組み込まれています。 アプローチの重要な部分は、システム全体を積極的に監視することです。これにより、運用システムが展開前にどのように維持されるかを理解し、容量を追加する必要がある場所を判断できます。 たとえば、メモリ使用量のスパイクの可能性について洞察を得ると、開始前に書き込みロックが発生する可能性があります。

展開を監視するために、MongoDBは次のコマンドのいくつかを提供します-

モンゴスタット

このコマンドは、実行中のすべてのmongodインスタンスのステータスをチェックし、データベース操作のカウンターを返します。 これらのカウンタには、挿入、クエリ、更新、削除、およびカーソルが含まれます。 また、コマンドは、ページフォールトが発生したときに表示され、ロックの割合を示します。 これは、メモリが不足していて、書き込み容量に達しているか、パフォーマンスの問題があることを意味します。

コマンドを実行するには、mongodインスタンスを起動します。 別のコマンドプロンプトで、mongodbインストールの bin ディレクトリに移動し、 mongostat と入力します。

D:\set up\mongodb\bin>mongostat

以下は、コマンドの出力です-

画像:/mongodb/images/mongostat.png [mongostat]画像:/mongodb/images/mongostat2.jpg [mongostat2]

モンゴトップ

このコマンドは、MongoDBインスタンスの読み取りおよび書き込みアクティビティをコレクションごとに追跡および報告します。 デフォルトでは、 mongotop は1秒ごとに情報を返しますが、それに応じて情報を変更できます。 この読み取りおよび書き込みアクティビティがアプリケーションの意図と一致することを確認する必要があります。また、一度にデータベースへの書き込みが多すぎたり、ディスクからの読み取りが多すぎたり、ワーキングセットのサイズを超えていないことを確認してください。

コマンドを実行するには、mongodインスタンスを起動します。 別のコマンドプロンプトで、mongodbインストールの bin ディレクトリに移動し、 mongotop と入力します。

D:\set up\mongodb\bin>mongotop

以下は、コマンドの出力です-

画像:/mongodb/images/mongotop.png [mongotop]画像:/mongodb/images/mongotop2.jpg [mongotop2]

*mongotop* コマンドを変更して情報を返す頻度を減らすには、mongotopコマンドの後に特定の番号を指定します。
D:\set up\mongodb\bin>mongotop 30

上記の例は、30秒ごとに値を返します。

MongoDBツールとは別に、10genはダッシュボードを提供し、クラスター全体のメトリックのビューを提供する、無料のホスト型監視サービスであるMongoDB Management Service(MMS)を提供します。

MongoDB-Java

この章では、MongoDB JDBCドライバーをセットアップする方法を学びます。

インストール

JavaプログラムでMongoDBの使用を開始する前に、MongoDB JDBCドライバーとJavaがマシンにセットアップされていることを確認する必要があります。 マシンにJavaをインストールするためのJavaチュートリアルを確認できます。 次に、MongoDB JDBCドライバーのセットアップ方法を確認しましょう。

 *jar* mongodb-driver-3.11.2.jarとその依存関係mongodb-driver-core-3.11.2.jar。*をダウンロードする必要があります。 これらのjarファイルの最新リリースをダウンロードしてください。
* ダウンロードしたjarファイルをクラスパスに含める必要があります。

データベースに接続する

データベースに接続するには、データベース名を指定する必要があります。データベースが存在しない場合は、MongoDBが自動的に作成します。

以下は、データベースに接続するためのコードスニペットです-

import com.mongodb.client.MongoDatabase;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
public class ConnectToDB {

   public static void main( String args[] ) {

     //Creating a Mongo client
      MongoClient mongo = new MongoClient( "localhost" , 27017 );

     //Creating Credentials
      MongoCredential credential;
      credential = MongoCredential.createCredential("sampleUser", "myDb",
         "password".toCharArray());
      System.out.println("Connected to the database successfully");

     //Accessing the database
      MongoDatabase database = mongo.getDatabase("myDb");
      System.out.println("Credentials ::"+ credential);
   }
}

次に、上記のプログラムをコンパイルして実行し、以下に示すようにデータベースmyDbを作成します。

$javac ConnectToDB.java
$java ConnectToDB

実行すると、上記のプログラムは次の出力を提供します。

Connected to the database successfully
Credentials ::MongoCredential{
   mechanism = null,
   userName = 'sampleUser',
   source = 'myDb',
   password = <hidden>,
   mechanismProperties = {}
}

コレクションを作成する

コレクションを作成するには、 com.mongodb.client.MongoDatabase クラスの* createCollection()*メソッドを使用します。

以下は、コレクションを作成するためのコードスニペットです-

import com.mongodb.client.MongoDatabase;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
public class CreatingCollection {

   public static void main( String args[] ) {

     //Creating a Mongo client
      MongoClient mongo = new MongoClient( "localhost" , 27017 );

     //Creating Credentials
      MongoCredential credential;
      credential = MongoCredential.createCredential("sampleUser", "myDb",
         "password".toCharArray());
      System.out.println("Connected to the database successfully");

     //Accessing the database
      MongoDatabase database = mongo.getDatabase("myDb");

     //Creating a collection
      database.createCollection("sampleCollection");
      System.out.println("Collection created successfully");
   }
}

コンパイルすると、上記のプログラムはあなたに次の結果を与えます-

Connected to the database successfully
Collection created successfully

コレクションの取得/選択

データベースからコレクションを取得/選択するには、 com.mongodb.client.MongoDatabase クラスの* getCollection()*メソッドを使用します。

以下は、コレクションを取得/選択するプログラムです-

import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
public class selectingCollection {

   public static void main( String args[] ) {

     //Creating a Mongo client
      MongoClient mongo = new MongoClient( "localhost" , 27017 );

     //Creating Credentials
      MongoCredential credential;
      credential = MongoCredential.createCredential("sampleUser", "myDb",
         "password".toCharArray());
      System.out.println("Connected to the database successfully");

     //Accessing the database
      MongoDatabase database = mongo.getDatabase("myDb");

     //Creating a collection
      System.out.println("Collection created successfully");
     //Retrieving a collection
      MongoCollection<Document> collection = database.getCollection("myCollection");
      System.out.println("Collection myCollection selected successfully");
   }
}

コンパイルすると、上記のプログラムはあなたに次の結果を与えます-

Connected to the database successfully
Collection created successfully
Collection myCollection selected successfully

ドキュメントを挿入する

MongoDBにドキュメントを挿入するには、 com.mongodb.client.MongoCollection クラスの* insert()*メソッドが使用されます。

以下は、ドキュメントを挿入するためのコードスニペットです-

import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
import com.mongodb.MongoClient;
public class InsertingDocument {
    public static void main( String args[] ) {

   //Creating a Mongo client
    MongoClient mongo = new MongoClient( "localhost" , 27017 );

   //Accessing the database
    MongoDatabase database = mongo.getDatabase("myDb");

   //Creating a collection
    database.createCollection("sampleCollection");
    System.out.println("Collection created successfully");

   //Retrieving a collection
    MongoCollection<Document> collection = database.getCollection("sampleCollection");
    System.out.println("Collection sampleCollection selected successfully");
    Document document = new Document("title", "MongoDB")
    .append("description", "database")
    .append("likes", 100)
    .append("url", "http://www.finddevguides.com/mongodb/")
    .append("by", "tutorials point");

   //Inserting document into the collection
    collection.insertOne(document);
    System.out.println("Document inserted successfully");
}

コンパイルすると、上記のプログラムはあなたに次の結果を与えます-

Connected to the database successfully
Collection sampleCollection selected successfully
Document inserted successfully

すべてのドキュメントを取得

コレクションからすべてのドキュメントを選択するには、 com.mongodb.client.MongoCollection クラスの* find()*メソッドが使用されます。 このメソッドはカーソルを返すため、このカーソルを繰り返す必要があります。

以下は、すべてのドキュメントを選択するプログラムです-

import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.bson.Document;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
public class RetrievingAllDocuments {
    public static void main( String args[] ) {

       //Creating a Mongo client
        MongoClient mongo = new MongoClient( "localhost" , 27017 );

       //Creating Credentials
        MongoCredential credential;
        credential = MongoCredential.createCredential("sampleUser", "myDb", "password".toCharArray());
        System.out.println("Connected to the database successfully");

       //Accessing the database
        MongoDatabase database = mongo.getDatabase("myDb");

       //Retrieving a collection
        MongoCollection<Document> collection = database.getCollection("sampleCollection");
        System.out.println("Collection sampleCollection selected successfully");
        Document document1 = new Document("title", "MongoDB")
        .append("description", "database")
        .append("likes", 100)
        .append("url", "http://www.finddevguides.com/mongodb/")
        .append("by", "tutorials point");
        Document document2 = new Document("title", "RethinkDB")
        .append("description", "database")
        .append("likes", 200)
        .append("url", "http://www.finddevguides.com/rethinkdb/")
        .append("by", "tutorials point");
        List<Document> list = new ArrayList<Document>();
        list.add(document1);
        list.add(document2);
        collection.insertMany(list);
       //Getting the iterable object
        FindIterable<Document> iterDoc = collection.find();
        int i = 1;
       //Getting the iterator
        Iterator it = iterDoc.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
            i++;
        }
    }
}

コンパイルすると、上記のプログラムはあなたに次の結果を与えます-

Connected to the database successfully
Collection sampleCollection selected successfully
Document{{_id=5dce4e9ff68a9c2449e197b2, title=MongoDB, description=database, likes=100, url=http://www.finddevguides.com/mongodb/, by=tutorials point}}
Document{{_id=5dce4e9ff68a9c2449e197b3, title=RethinkDB, description=database, likes=200, url=http://www.finddevguides.com/rethinkdb/, by=tutorials point}}

ドキュメントを更新

コレクションからドキュメントを更新するには、 com.mongodb.client.MongoCollection クラスの* updateOne()*メソッドが使用されます。

以下は、最初のドキュメントを選択するプログラムです-

import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Updates;
import java.util.Iterator;
import org.bson.Document;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
public class UpdatingDocuments {

   public static void main( String args[] ) {

     //Creating a Mongo client
      MongoClient mongo = new MongoClient( "localhost" , 27017 );

     //Creating Credentials
      MongoCredential credential;
      credential = MongoCredential.createCredential("sampleUser", "myDb",
         "password".toCharArray());
      System.out.println("Connected to the database successfully");

     //Accessing the database
      MongoDatabase database = mongo.getDatabase("myDb");
     //Retrieving a collection
      MongoCollection<Document> collection = database.getCollection("sampleCollection");
      System.out.println("Collection myCollection selected successfully");
      collection.updateOne(Filters.eq("title", 1), Updates.set("likes", 150));
      System.out.println("Document update successfully...");

     //Retrieving the documents after updation
     //Getting the iterable object
      FindIterable<Document> iterDoc = collection.find();
      int i = 1;
     //Getting the iterator
      Iterator it = iterDoc.iterator();
      while (it.hasNext()) {
         System.out.println(it.next());
         i++;
      }
   }
}

コンパイルすると、上記のプログラムはあなたに次の結果を与えます-

Connected to the database successfully
Collection myCollection selected successfully
Document update successfully...
Document{{_id=5dce4e9ff68a9c2449e197b2, title=MongoDB, description=database, likes=100, url=http://www.finddevguides.com/mongodb/, by=tutorials point}}
Document{{_id=5dce4e9ff68a9c2449e197b3, title=RethinkDB, description=database, likes=200, url=http://www.finddevguides.com/rethinkdb/, by=tutorials point}}

ドキュメントを削除する

コレクションからドキュメントを削除するには、 com.mongodb.client.MongoCollection クラスの* deleteOne()*メソッドを使用する必要があります。

以下は、ドキュメントを削除するプログラムです-

import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import java.util.Iterator;
import org.bson.Document;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
public class DeletingDocuments {

   public static void main( String args[] ) {

     //Creating a Mongo client
      MongoClient mongo = new MongoClient( "localhost" , 27017 );

     //Creating Credentials
      MongoCredential credential;
      credential = MongoCredential.createCredential("sampleUser", "myDb",
         "password".toCharArray());
      System.out.println("Connected to the database successfully");

     //Accessing the database
      MongoDatabase database = mongo.getDatabase("myDb");
     //Retrieving a collection
      MongoCollection<Document> collection = database.getCollection("sampleCollection");
      System.out.println("Collection sampleCollection selected successfully");
     //Deleting the documents
      collection.deleteOne(Filters.eq("title", "MongoDB"));
      System.out.println("Document deleted successfully...");

     //Retrieving the documents after updation
     //Getting the iterable object
      FindIterable<Document> iterDoc = collection.find();
      int i = 1;
     //Getting the iterator
      Iterator it = iterDoc.iterator();
      while (it.hasNext()) {
         System.out.println(it.next());
         i++;
      }
   }
}

コンパイルすると、上記のプログラムはあなたに次の結果を与えます-

Connected to the database successfully
Collection sampleCollection selected successfully
Document deleted successfully...
Document{{_id=5dce4e9ff68a9c2449e197b3, title=RethinkDB, description=database, likes=200, url=http://www.finddevguides.com/rethinkdb/, by=tutorials point}}

コレクションの削除

データベースからコレクションを削除するには、 com.mongodb.client.MongoCollection クラスの* drop()*メソッドを使用する必要があります。

以下は、コレクションを削除するプログラムです-

import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
public class DropingCollection {

   public static void main( String args[] ) {
     //Creating a Mongo client
      MongoClient mongo = new MongoClient( "localhost" , 27017 );
     //Creating Credentials
      MongoCredential credential;
      credential = MongoCredential.createCredential("sampleUser", "myDb",
         "password".toCharArray());
      System.out.println("Connected to the database successfully");

     //Accessing the database
      MongoDatabase database = mongo.getDatabase("myDb");

     //Creating a collection
      System.out.println("Collections created successfully");
     //Retrieving a collection
      MongoCollection<Document> collection = database.getCollection("sampleCollection");
     //Dropping a Collection
      collection.drop();
      System.out.println("Collection dropped successfully");
   }
}

コンパイルすると、上記のプログラムはあなたに次の結果を与えます-

Connected to the database successfully
Collection sampleCollection selected successfully
Collection dropped successfully

すべてのコレクションのリスト

データベース内のすべてのコレクションをリストするには、 com.mongodb.client.MongoDatabase クラスの* listCollectionNames()*メソッドを使用する必要があります。

以下は、データベースのすべてのコレクションを一覧表示するプログラムです-

import com.mongodb.client.MongoDatabase;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
public class ListOfCollection {

   public static void main( String args[] ) {

     //Creating a Mongo client
      MongoClient mongo = new MongoClient( "localhost" , 27017 );
     //Creating Credentials
      MongoCredential credential;
      credential = MongoCredential.createCredential("sampleUser", "myDb",
         "password".toCharArray());
      System.out.println("Connected to the database successfully");

     //Accessing the database
      MongoDatabase database = mongo.getDatabase("myDb");
      System.out.println("Collection created successfully");
      for (String name : database.listCollectionNames()) {
         System.out.println(name);
      }
   }
}

コンパイルすると、上記のプログラムはあなたに次の結果を与えます-

Connected to the database successfully
Collection created successfully
myCollection
myCollection1
myCollection5

残りのMongoDBメソッド* save()、limit()、skip()、sort()*など 後続のチュートリアルで説明したのと同じように機能します。

MongoDB-PHP

PHPでMongoDBを使用するには、MongoDB PHPドライバーを使用する必要があります。 Download PHP Driverからドライバーをダウンロードします。 必ず最新リリースをダウンロードしてください。 アーカイブを解凍し、php_mongo.dllをPHP拡張ディレクトリ(デフォルトでは「ext」)に配置し、次の行をphp.iniファイルに追加します-

extension = php_mongo.dll

接続してデータベースを選択する

接続を確立するには、データベース名を指定する必要があります。データベースが存在しない場合は、MongoDBが自動的に作成します。

以下は、データベースに接続するためのコードスニペットです-

<?php
  //connect to mongodb
   $m = new MongoClient();

   echo "Connection to database successfully";
  //select a database
   $db = $m->mydb;

   echo "Database mydb selected";
?>

プログラムが実行されると、次の結果が生成されます-

Connection to database successfully
Database mydb selected

コレクションを作成する

以下は、コレクションを作成するためのコードスニペットです-

<?php
  //connect to mongodb
   $m = new MongoClient();
   echo "Connection to database successfully";

  //select a database
   $db = $m->mydb;
   echo "Database mydb selected";
   $collection = $db->createCollection("mycol");
   echo "Collection created succsessfully";
?>

プログラムが実行されると、次の結果が生成されます-

Connection to database successfully
Database mydb selected
Collection created succsessfully

ドキュメントを挿入する

MongoDBにドキュメントを挿入するには、* insert()*メソッドが使用されます。

以下は、ドキュメントを挿入するためのコードスニペットです-

<?php
  //connect to mongodb
   $m = new MongoClient();
   echo "Connection to database successfully";

  //select a database
   $db = $m->mydb;
   echo "Database mydb selected";
   $collection = $db->mycol;
   echo "Collection selected succsessfully";

   $document = array(
      "title" => "MongoDB",
      "description" => "database",
      "likes" => 100,
      "url" => "http://www.finddevguides.com/mongodb/",
      "by" => "tutorials point"
   );

   $collection->insert($document);
   echo "Document inserted successfully";
?>

プログラムが実行されると、次の結果が生成されます-

Connection to database successfully
Database mydb selected
Collection selected succsessfully
Document inserted successfully

すべてのドキュメントを検索

コレクションからすべてのドキュメントを選択するには、find()メソッドが使用されます。

以下は、すべてのドキュメントを選択するためのコードスニペットです-

<?php
  //connect to mongodb
   $m = new MongoClient();
   echo "Connection to database successfully";

  //select a database
   $db = $m->mydb;
   echo "Database mydb selected";
   $collection = $db->mycol;
   echo "Collection selected succsessfully";
   $cursor = $collection->find();
  //iterate cursor to display title of documents

   foreach ($cursor as $document) {
      echo $document["title"] . "\n";
   }
?>

プログラムが実行されると、次の結果が生成されます-

Connection to database successfully
Database mydb selected
Collection selected succsessfully {
   "title": "MongoDB"
}

ドキュメントを更新する

ドキュメントを更新するには、update()メソッドを使用する必要があります。

次の例では、挿入されたドキュメントのタイトルを* MongoDBチュートリアル*に更新します。 以下は、ドキュメントを更新するためのコードスニペットです-

<?php
  //connect to mongodb
   $m = new MongoClient();
   echo "Connection to database successfully";

  //select a database
   $db = $m->mydb;
   echo "Database mydb selected";
   $collection = $db->mycol;
   echo "Collection selected succsessfully";
  //now update the document
   $collection->update(array("title"=>"MongoDB"),
      array('$set'=>array("title"=>"MongoDB Tutorial")));
   echo "Document updated successfully";

  //now display the updated document
   $cursor = $collection->find();

  //iterate cursor to display title of documents
   echo "Updated document";

   foreach ($cursor as $document) {
      echo $document["title"] . "\n";
   }
?>

プログラムが実行されると、次の結果が生成されます-

Connection to database successfully
Database mydb selected
Collection selected succsessfully
Document updated successfully
Updated document {
   "title": "MongoDB Tutorial"
}

ドキュメントを削除する

ドキュメントを削除するには、remove()メソッドを使用する必要があります。

次の例では、 MongoDB Tutorial というタイトルのドキュメントを削除します。 以下は、ドキュメントを削除するためのコードスニペットです-

<?php
  //connect to mongodb
   $m = new MongoClient();
   echo "Connection to database successfully";

  //select a database
   $db = $m->mydb;
   echo "Database mydb selected";
   $collection = $db->mycol;
   echo "Collection selected succsessfully";

  //now remove the document
   $collection->remove(array("title"=>"MongoDB Tutorial"),false);
   echo "Documents deleted successfully";

  //now display the available documents
   $cursor = $collection->find();

  //iterate cursor to display title of documents
   echo "Updated document";

   foreach ($cursor as $document) {
      echo $document["title"] . "\n";
   }
?>

プログラムが実行されると、次の結果が生成されます-

Connection to database successfully
Database mydb selected
Collection selected successfully
Documents deleted successfully

上記の例では、2番目のパラメーターはブール型で、* remove()メソッドの *justOne フィールドに使用されます。

残りのMongoDBメソッド* findOne()、save()、limit()、skip()、sort()*など 上で説明したのと同じ働きをします。

MongoDB-関係

MongoDBの関係は、さまざまなドキュメントが論理的に相互にどのように関連しているかを表します。 関係は、 Embedded および Referenced アプローチを介してモデル化できます。 このような関係は、1:1、1:N、N:1、またはN:Nのいずれかです。

ユーザーのアドレスを保存する場合を考えてみましょう。 したがって、1人のユーザーが複数のアドレスを持ち、これを1:Nの関係にすることができます。

以下は、 user ドキュメントのサンプルドキュメント構造です-

{
   "_id":ObjectId("52ffc33cd85242f436000001"),
   "name": "Tom Hanks",
   "contact": "987654321",
   "dob": "01-01-1991"
}

以下は、 address 文書のサンプル文書構造です-

{
   "_id":ObjectId("52ffc4a5d85242602e000000"),
   "building": "22 A, Indiana Apt",
   "pincode": 123456,
   "city": "Los Angeles",
   "state": "California"
}

埋め込み関係のモデリング

埋め込みアプローチでは、アドレスドキュメントをユーザードキュメント内に埋め込みます。

> db.users.insert({
    {
        "_id":ObjectId("52ffc33cd85242f436000001"),
        "contact": "987654321",
        "dob": "01-01-1991",
        "name": "Tom Benzamin",
        "address": [
            {
                "building": "22 A, Indiana Apt",
                "pincode": 123456,
                "city": "Los Angeles",
                "state": "California"
            },
            {
                "building": "170 A, Acropolis Apt",
                "pincode": 456789,
                "city": "Chicago",
                "state": "Illinois"
            }
        ]
    }
})

このアプローチでは、関連するすべてのデータが単一のドキュメントに保持されるため、取得と管理が簡単になります。 文書全体は、次のような単一のクエリで取得できます-

>db.users.findOne({"name":"Tom Benzamin"},{"address":1})

上記のクエリでは、 dbusers がそれぞれデータベースとコレクションであることに注意してください。

欠点は、埋め込みドキュメントのサイズが大きくなり続けると、読み取り/書き込みパフォーマンスに影響を与える可能性があることです。

参照関係のモデリング

これは、正規化された関係を設計するアプローチです。 このアプローチでは、ユーザー文書と住所文書の両方が個別に維持されますが、ユーザー文書には住所文書の id フィールドを参照するフィールドが含まれます。

{
   "_id":ObjectId("52ffc33cd85242f436000001"),
   "contact": "987654321",
   "dob": "01-01-1991",
   "name": "Tom Benzamin",
   "address_ids": [
      ObjectId("52ffc4a5d85242602e000000"),
      ObjectId("52ffc4a5d85242602e000001")
   ]
}

上記のように、ユーザードキュメントには、対応するアドレスのObjectIdを含む配列フィールド address_ids が含まれています。 これらのObjectIdを使用して、住所ドキュメントを照会し、そこから住所の詳細を取得できます。 このアプローチでは、2つのクエリが必要になります。1つ目は user ドキュメントから address_ids フィールドを取得し、2つ目は address コレクションからこれらのアドレスを取得します。

>var result = db.users.findOne({"name":"Tom Benzamin"},{"address_ids":1})
>var addresses = db.address.find({"_id":{"$in":result["address_ids"]}})

MongoDB-データベース参照

MongoDBリレーションシップの最後の章で見たように、MongoDBに正規化されたデータベース構造を実装するために、参照ドキュメントのIDを他のドキュメント内に手動で保存する*手動参照*とも呼ばれる*参照リレーションシップ*の概念を使用します。 ただし、ドキュメントに異なるコレクションからの参照が含まれる場合は、 MongoDB DBRefs を使用できます。

DBRefと手動参照

手動参照の代わりにDBRefを使用するシナリオの例として、異なるコレクション(address_home、address_office、address_mailingなど)に異なるタイプのアドレス(home、office、mailingなど)を格納しているデータベースを考えます。 現在、 user コレクションのドキュメントが住所を参照する場合、住所タイプに基づいてどのコレクションを調べるかを指定する必要もあります。 ドキュメントが多くのコレクションのドキュメントを参照するようなシナリオでは、DBRefを使用する必要があります。

DBRefを使用する

DBRefには3つのフィールドがあります-

  • $ ref -このフィールドは、参照されるドキュメントのコレクションを指定します
  • $ id -このフィールドは、参照されるドキュメントの_idフィールドを指定します
  • $ db -これはオプションのフィールドであり、参照されるドキュメントが存在するデータベースの名前が含まれます

コードスニペットに示すように、DBRefフィールド*アドレス*を持つサンプルユーザードキュメントを考えてください-

{
   "_id":ObjectId("53402597d852426020000002"),
   "address": {
   "$ref": "address_home",
   "$id": ObjectId("534009e4d852427820000002"),
   "$db": "finddevguides"},
   "contact": "987654321",
   "dob": "01-01-1991",
   "name": "Tom Benzamin"
}

ここの address DBRefフィールドは、参照されるアドレスドキュメントが finddevguides データベースの address_home コレクションにあり、534009e4d852427820000002のIDを持っていることを指定します。

次のコードは、DBRefの $ id パラメーターで指定されたIDを持つドキュメントの $ ref パラメーター(この例では address_home )で指定されたコレクションを動的に検索します。

>var user = db.users.findOne({"name":"Tom Benzamin"})
>var dbRef = user.address
>db[dbRef.$ref].findOne({"_id":(dbRef.$id)})

上記のコードは、 address_home コレクションに存在する次の住所ドキュメントを返します-

{
   "_id" : ObjectId("534009e4d852427820000002"),
   "building" : "22 A, Indiana Apt",
   "pincode" : 123456,
   "city" : "Los Angeles",
   "state" : "California"
}

MongoDB-対象クエリ

この章では、対象クエリについて学習します。

対象クエリとは何ですか?

公式のMongoDBドキュメントによると、対象クエリは次のクエリです-

  • クエリのすべてのフィールドはインデックスの一部です。
  • クエリで返されるすべてのフィールドは同じインデックスにあります。

クエリに存在するすべてのフィールドはインデックスの一部であるため、MongoDBはクエリ条件に一致し、実際にドキュメント内を調べることなく同じインデックスを使用して結果を返します。 RAMにはインデックスが存在するため、ドキュメントをスキャンしてデータを取得するのに比べて、インデックスからデータを取得する方がはるかに高速です。

対象クエリの使用

カバーされたクエリをテストするには、 users コレクションの次のドキュメントを考慮してください-

{
   "_id": ObjectId("53402597d852426020000002"),
   "contact": "987654321",
   "dob": "01-01-1991",
   "gender": "M",
   "name": "Tom Benzamin",
   "user_name": "tombenzamin"
}

まず、次のクエリを使用して、フィールド gender および user_nameusers コレクションの複合インデックスを作成します-

>db.users.ensureIndex({gender:1,user_name:1})

さて、このインデックスは次のクエリをカバーします-

>db.users.find({gender:"M"},{user_name:1,_id:0})

つまり、上記のクエリでは、MongoDBはデータベースドキュメントを調べません。 代わりに、インデックス付きデータから必要なデータをフェッチしますが、これは非常に高速です。

インデックスには _id フィールドが含まれていないため、MongoDBはデフォルトですべてのクエリで_idフィールドを返すため、クエリの結果セットから明示的に除外しています。 したがって、次のクエリは、上記で作成されたインデックス内ではカバーされませんでした-

>db.users.find({gender:"M"},{user_name:1})

最後に、インデックスはクエリをカバーできないことを覚えておいてください-

  • インデックス付きフィールドのいずれかが配列です
  • インデックス付きフィールドのいずれかがサブドキュメントです

MongoDB-クエリの分析

クエリの分析は、データベースとインデックス作成の設計の効果を測定する上で非常に重要な側面です。 頻繁に使用される $ explain および $ hint クエリについて学習します。

$ explainを使用する

*$ explain* 演算子は、クエリ、クエリで使用されるインデックス、およびその他の統計に関する情報を提供します。 インデックスがどの程度最適化されているかを分析するときに非常に役立ちます。

前の章では、次のクエリを使用して、フィールド gender および user_nameusers コレクションのインデックスを既に作成しました-

>db.users.createIndex({gender:1,user_name:1})
{
    "numIndexesBefore" : 2,
    "numIndexesAfter" : 2,
    "note" : "all indexes already exist",
    "ok" : 1
}

次のクエリで $ explain を使用します-

>db.users.find({gender:"M"},{user_name:1,_id:0}).explain()

上記のexplain()クエリは、次の分析結果を返します-

{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "mydb.users",
        "indexFilterSet" : false,
        "parsedQuery" : {
            "gender" : {
                "$eq" : "M"
            }
        },
        "queryHash" : "B4037D3C",
        "planCacheKey" : "DEAAE17C",
        "winningPlan" : {
            "stage" : "PROJECTION_COVERED",
            "transformBy" : {
                "user_name" : 1,
                "_id" : 0
            },
            "inputStage" : {
                "stage" : "IXSCAN",
                "keyPattern" : {
                    "gender" : 1,
                    "user_name" : 1
                },
                "indexName" : "gender_1_user_name_1",
                "isMultiKey" : false,
                "multiKeyPaths" : {
                    "gender" : [ ],
                    "user_name" : [ ]
                },
                "isUnique" : false,
                "isSparse" : false,
                "isPartial" : false,
                "indexVersion" : 2,
                "direction" : "forward",
                "indexBounds" : {
                    "gender" : [
                        "[\"M\", \"M\"]"
                    ],
                    "user_name" : [
                        "[MinKey, MaxKey]"
                    ]
                }
            }
        },
        "rejectedPlans" : [ ]
    },
    "serverInfo" : {
        "host" : "Krishna",
        "port" : 27017,
        "version" : "4.2.1",
        "gitVersion" : "edf6d45851c0b9ee15548f0f847df141764a317e"
    },
    "ok" : 1
}

この結果セットのフィールドを見てみましょう-

  • indexOnly の真の値は、このクエリがインデックスを使用したことを示します。
  • cursor フィールドは、使用するカーソルのタイプを指定します。 BTreeCursorタイプは、インデックスが使用されたことを示し、使用されたインデックスの名前も示します。 BasicCursorは、インデックスを使用せずにフルスキャンが行われたことを示します。
  • n は、一致したドキュメントの数を示します。
  • nscannedObjects は、スキャンされたドキュメントの総数を示します。
  • nscanned は、スキャンされたドキュメントまたはインデックスエントリの総数を示します。

$ hintを使用する

*$ hint* 演算子は、クエリオプティマイザーが指定されたインデックスを使用してクエリを実行するように強制します。 これは、異なるインデックスを使用したクエリのパフォーマンスをテストする場合に特に便利です。 たとえば、次のクエリは、このクエリに使用されるフィールド *gender* および *user_name* のインデックスを指定します-
>db.users.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1})
{ "user_name" : "tombenzamin" }

$ explainを使用して上記のクエリを分析するには-

>db.users.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1}).explain()

これはあなたに次の結果を与えます-

{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "mydb.users",
        "indexFilterSet" : false,
        "parsedQuery" : {
            "gender" : {
                "$eq" : "M"
            }
        },
        "queryHash" : "B4037D3C",
        "planCacheKey" : "DEAAE17C",
        "winningPlan" : {
            "stage" : "PROJECTION_COVERED",
            "transformBy" : {
                "user_name" : 1,
                "_id" : 0
            },
            "inputStage" : {
                "stage" : "IXSCAN",
                "keyPattern" : {
                    "gender" : 1,
                    "user_name" : 1
                },
                "indexName" : "gender_1_user_name_1",
                "isMultiKey" : false,
                "multiKeyPaths" : {
                    "gender" : [ ],
                    "user_name" : [ ]
                },
                "isUnique" : false,
                "isSparse" : false,
                "isPartial" : false,
                "indexVersion" : 2,
                "direction" : "forward",
                "indexBounds" : {
                    "gender" : [
                        "[\"M\", \"M\"]"
                    ],
                    "user_name" : [
                        "[MinKey, MaxKey]"
                    ]
                }
            }
        },
        "rejectedPlans" : [ ]
    },
    "serverInfo" : {
        "host" : "Krishna",
        "port" : 27017,
        "version" : "4.2.1",
        109
        "gitVersion" : "edf6d45851c0b9ee15548f0f847df141764a317e"
    },
    "ok" : 1
}

MongoDB-アトミックオペレーション

MongoDBは*マルチドキュメントアトミックトランザクション*をサポートしていません。 ただし、単一のドキュメントに対してアトミック操作を提供します。 そのため、ドキュメントに100個のフィールドがある場合、更新ステートメントはすべてのフィールドを更新するか、まったく更新しないため、ドキュメントレベルで原子性が維持されます。

原子操作のモデルデータ

原子性を維持するための推奨アプローチは、すべての関連情報を保持することです。これは、*埋め込み文書*を使用して単一の文書で頻繁に更新されます。 これにより、1つのドキュメントのすべての更新がアトミックになります。

以下に示すように、productDetailsという名前のコレクションを作成し、それにドキュメントを挿入したと仮定します-

>db.createCollection("products")
{ "ok" : 1 }
> db.productDetails.insert(
    {
        "_id":1,
        "product_name": "Samsung S3",
        "category": "mobiles",
        "product_total": 5,
        "product_available": 3,
        "product_bought_by": [
            {
                "customer": "john",
                "date": "7-Jan-2014"
            },
            {
                "customer": "mark",
                "date": "8-Jan-2014"
            }
        ]
    }
)
WriteResult({ "nInserted" : 1 })
>

このドキュメントでは、 product_bought_by フィールドに製品を購入した顧客の情報を埋め込みました。 これで、新しい顧客が製品を購入するたびに、 product_available フィールドを使用して、製品がまだ使用可能かどうかを最初に確認します。 可能であれば、product_availableフィールドの値を減らし、product_bought_byフィールドに新しい顧客の埋め込みドキュメントを挿入します。 同じ機能でドキュメントを検索および更新するため、この機能には findAndModify コマンドを使用します。

>db.products.findAndModify({
   query:{_id:2,product_available:{$gt:0}},
   update:{
      $inc:{product_available:-1},
      $push:{product_bought_by:{customer:"rob",date:"9-Jan-2014"}}
   }
})

埋め込みドキュメントとfindAndModifyクエリを使用するアプローチにより、製品が利用可能な場合にのみ、製品購入情報が更新されます。 そして、同じトランザクション内にあるこのトランザクション全体はアトミックです。

これとは対照的に、製品の可用性と製品を購入したユーザーに関する情報を別々に保持するシナリオを検討してください。 この場合、最初のクエリを使用して、製品が利用可能かどうかを最初に確認します。 次に、2番目のクエリで購入情報を更新します。 ただし、これら2つのクエリの実行の間に、他のユーザーが製品を購入し、使用できなくなる可能性があります。 これを知らなくても、2番目のクエリは最初のクエリの結果に基づいて購入情報を更新します。 利用できない製品を販売しているため、これによりデータベースの一貫性が失われます。

MongoDB-高度なインデックス作成

  • ユーザー*コレクションの次のドキュメントを考慮してください-
{
   "address": {
      "city": "Los Angeles",
      "state": "California",
      "pincode": "123"
   },
   "tags": [
      "music",
      "cricket",
      "blogs"
   ],
   "name": "Tom Benzamin"
}

上記のドキュメントには、* addressサブドキュメント*と* tags配列*が含まれています。

配列フィールドのインデックス付け

ユーザーのタグに基づいてユーザードキュメントを検索するとします。 このために、コレクション内のタグ配列にインデックスを作成します。

配列にインデックスを作成すると、フィールドごとに個別のインデックスエントリが作成されます。 したがって、この場合、タグ配列にインデックスを作成すると、音楽、クリケット、ブログの値に対して個別のインデックスが作成されます。

タグ配列にインデックスを作成するには、次のコードを使用します-

>db.users.ensureIndex({"tags":1})

インデックスを作成した後、次のようにコレクションのタグフィールドを検索できます-

>db.users.find({tags:"cricket"})

適切なインデックスが使用されていることを確認するには、次の explain コマンドを使用します-

>db.users.find({tags:"cricket"}).explain()

上記のコマンドの結果、「cursor」:「BtreeCursor tags_1」となり、適切なインデックスが使用されていることが確認されます。

サブドキュメントフィールドのインデックス作成

都市、州、およびPINコードのフィールドに基づいてドキュメントを検索するとします。 これらのフィールドはすべて住所サブ文書フィールドの一部であるため、サブ文書のすべてのフィールドにインデックスを作成します。

サブ文書の3つのフィールドすべてにインデックスを作成するには、次のコードを使用します-

>db.users.ensureIndex({"address.city":1,"address.state":1,"address.pincode":1})

インデックスが作成されると、次のようにこのインデックスを利用してサブドキュメントフィールドを検索できます-

>db.users.find({"address.city":"Los Angeles"})

クエリ式は、指定されたインデックスの順序に従う必要があることに注意してください。 したがって、上記で作成されたインデックスは、次のクエリをサポートします-

>db.users.find({"address.city":"Los Angeles","address.state":"California"})

また、次のクエリをサポートします-

>db.users.find({"address.city":"LosAngeles","address.state":"California",
   "address.pincode":"123"})

MongoDB-インデックス作成の制限

この章では、インデックス作成の制限とその他のコンポーネントについて学習します。

余分なオーバーヘッド

すべてのインデックスはいくつかのスペースを占有し、挿入、更新、削除のたびにオーバーヘッドが発生します。 したがって、コレクションを読み取り操作にめったに使用しない場合は、インデックスを使用しないのが理にかなっています。

RAM使用量

インデックスはRAMに保存されるため、インデックスの合計サイズがRAMの制限を超えないようにする必要があります。 合計サイズがRAMサイズを増やすと、一部のインデックスの削除が開始され、パフォーマンスが低下します。

クエリの制限

インデックスを使用するクエリでは使用できません-

  • 正規表現または$ nin、$ notなどの否定演算子。
  • $ modなどの算術演算子
  • $ where句

したがって、クエリのインデックスの使用状況を常に確認することをお勧めします。

インデックスキーの制限

バージョン2.6以降、既存のインデックスフィールドの値がインデックスキーの制限を超えた場合、MongoDBはインデックスを作成しません。

インデックスキーの制限を超えるドキュメントの挿入

MongoDBは、このドキュメントのインデックス付きフィールドの値がインデックスキーの制限を超える場合、インデックス付きコレクションにドキュメントを挿入しません。 mongorestoreおよびmongoimportユーティリティの場合も同様です。

最大範囲

  • コレクションには64を超えるインデックスを含めることはできません。
  • インデックス名の長さは125文字を超えることはできません。
  • 複合インデックスには、最大31個のフィールドにインデックスを付けることができます。

MongoDB-ObjectId

これまでのすべての章でMongoDBオブジェクトIDを使用してきました。 この章では、ObjectIdの構造を理解します。

*ObjectId* は、次の構造を持つ12バイトのBSONタイプです-
  • UNIXエポックからの秒数を表す最初の4バイト
  • 次の3バイトはマシン識別子です
  • 次の2バイトは process id で構成されます
  • 最後の3バイトはランダムなカウンター値です

MongoDBは、ドキュメントの作成中に生成される各ドキュメントの _id フィールドのデフォルト値としてObjectIdsを使用します。 ObjectIdの複雑な組み合わせにより、すべての_idフィールドが一意になります。

新しいObjectIdの作成

新しいObjectIdを生成するには、次のコードを使用します-

>newObjectId = ObjectId()

上記のステートメントは、次の一意に生成されたIDを返しました-

ObjectId("5349b4ddd2781d08c09890f3")

MongoDBがObjectIdを生成する代わりに、12バイトのIDを提供することもできます-

>myObjectId = ObjectId("5349b4ddd2781d08c09890f4")

ドキュメントのタイムスタンプを作成する

_id ObjectIdはデフォルトで4バイトのタイムスタンプを保存するため、ほとんどの場合、ドキュメントの作成時間を保存する必要はありません。 あなたはgetTimestampメソッドを使用してドキュメントの作成時間を取得することができます-

>ObjectId("5349b4ddd2781d08c09890f4").getTimestamp()

これは、ISO日付形式でこのドキュメントの作成時間を返します-

ISODate("2014-04-12T21:49:17Z")

ObjectIdを文字列に変換する

場合によっては、文字列形式のObjectIdの値が必要になることがあります。 文字列のObjectIdを変換するには、次のコードを使用します-

>newObjectId.str

上記のコードは、GUIDの文字列形式を返します-

5349b4ddd2781d08c09890f3

MongoDB-マップ削減

MongoDBのドキュメントによると、 Map-reduce は、大量のデータを有用な集計結果に凝縮するためのデータ処理パラダイムです。 MongoDBは、map-reduce操作に mapReduce コマンドを使用します。 MapReduceは通常、大きなデータセットの処理に使用されます。

MapReduceコマンド

以下は、基本的なmapReduceコマンドの構文です-

>db.collection.mapReduce(
   function() {emit(key,value);}, //map function
   function(key,values) {return reduceFunction}, {  //reduce function
      out: collection,
      query: document,
      sort: document,
      limit: number
   }
)

map-reduce関数は最初にコレクションを照会し、次に結果ドキュメントをマップしてキーと値のペアを生成します。次に、キーと値のペアは複数の値を持つキーに基づいて削減されます。

上記の構文では-

  • map は、値をキーにマップし、キーと値のペアを出力するjavascript関数です
  • reduce は、同じキーを持つすべてのドキュメントを削減またはグループ化するJavaScript関数です
  • out は、map-reduceクエリ結果の場所を指定します
  • query は、ドキュメントを選択するためのオプションの選択基準を指定します
  • sort はオプションのソート基準を指定します
  • limit は、返されるドキュメントのオプションの最大数を指定します

MapReduceを使用する

ユーザー投稿を保存する次のドキュメント構造を検討してください。 ドキュメントには、ユーザーのuser_nameと投稿のステータスが保存されます。

{
   "post_text": "finddevguides is an awesome website for tutorials",
   "user_name": "mark",
   "status":"active"
}

ここで、 posts コレクションでmapReduce関数を使用して、すべてのアクティブな投稿を選択し、user_nameに基づいてグループ化し、次のコードを使用して各ユーザーの投稿数をカウントします-

>db.posts.mapReduce(
   function() { emit(this.user_id,1); },

   function(key, values) {return Array.sum(values)}, {
      query:{status:"active"},
      out:"post_total"
   }
)

上記のmapReduceクエリは、次の結果を出力します-

{
   "result" : "post_total",
   "timeMillis" : 9,
   "counts" : {
      "input" : 4,
      "emit" : 4,
      "reduce" : 2,
      "output" : 2
   },
   "ok" : 1,
}

結果は、合計4つのドキュメントがクエリ(ステータス:「アクティブ」)に一致し、マップ関数がキーと値のペアを持つ4つのドキュメントを発行し、最後にリデュース関数が同じキーを持つマップされたドキュメントを2にグループ化したことを示しています。

このmapReduceクエリの結果を表示するには、検索演算子を使用します-

>db.posts.mapReduce(
   function() { emit(this.user_id,1); },
   function(key, values) {return Array.sum(values)}, {
      query:{status:"active"},
      out:"post_total"
   }

).find()

上記のクエリは、ユーザー tommark の両方がアクティブ状態の2つの投稿を持っていることを示す次の結果を提供します-

{ "_id" : "tom", "value" : 2 }
{ "_id" : "mark", "value" : 2 }

同様に、MapReduceクエリを使用して、大規模で複雑な集計クエリを作成できます。 カスタムJavascript関数の使用は、非常に柔軟で強力なMapReduceを使用します。

MongoDB-テキスト検索

バージョン2.4から、MongoDBは文字列コンテンツ内を検索するためのテキストインデックスのサポートを開始しました。 テキスト検索*は、ステミングテクニックを使用して、 a、an、the、*などのステミングストップワードをドロップすることにより、文字列フィールドで指定されたワードを検索します 現在、MongoDBは約15の言語をサポートしています。

テキスト検索を有効にする

当初、テキスト検索は実験的な機能でしたが、バージョン2.6以降、デフォルトで構成が有効になっています。

テキストインデックスの作成

投稿テキストとそのタグを含む posts コレクションの下の次のドキュメントを検討してください-

> db.posts.insert({
   "post_text": "enjoy the mongodb articles on finddevguides",
   "tags": ["mongodb", "finddevguides"]
}
{
    "post_text" : "writing tutorials on mongodb",
    "tags" : [ "mongodb", "tutorial" ]
})
WriteResult({ "nInserted" : 1 })

post_textフィールドにテキストインデックスを作成して、投稿のテキスト内を検索できるようにします-

>db.posts.createIndex({post_text:"text"})
{
    "createdCollectionAutomatically" : true,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}

テキストインデックスの使用

post_textフィールドにテキストインデックスを作成したので、テキストに finddevguides という単語が含まれるすべての投稿を検索します。

> db.posts.find({$text:{$search:"finddevguides"}}).pretty()
{
    "_id" : ObjectId("5dd7ce28f1dd4583e7103fe0"),
    "post_text" : "enjoy the mongodb articles on finddevguides",
    "tags" : [
        "mongodb",
        "finddevguides"
    ]
}

上記のコマンドは、投稿テキストに finddevguides という単語を含む次の結果ドキュメントを返しました-

{
   "_id" : ObjectId("53493d14d852429c10000002"),
   "post_text" : "enjoy the mongodb articles on finddevguides",
   "tags" : [ "mongodb", "finddevguides" ]
}

テキストインデックスの削除

既存のテキストインデックスを削除するには、最初に次のクエリを使用してインデックスの名前を見つけます-

>db.posts.getIndexes()
[
    {
        "v" : 2,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "mydb.posts"
    },
    {
        "v" : 2,
        "key" : {
            "fts" : "text",
            "ftsx" : 1
        },
        "name" : "post_text_text",
        "ns" : "mydb.posts",
        "weights" : {
            "post_text" : 1
        },
        "default_language" : "english",
        "language_override" : "language",
        "textIndexVersion" : 3
    }
]
>

上記のクエリからインデックスの名前を取得したら、次のコマンドを実行します。 ここで、 post_text_text はインデックスの名前です。

>db.posts.dropIndex("post_text_text")
{ "nIndexesWas" : 2, "ok" : 1 }

MongoDB-正規表現

正規表現は、すべての言語で頻繁に使用され、任意の文字列のパターンまたは単語を検索します。 MongoDBは、 $ regex 演算子を使用した文字列パターンマッチングの正規表現機能も提供します。 MongoDBは、PCRE(Perl Compatible Regular Expression)を正規表現言語として使用します。

テキスト検索とは異なり、正規表現を使用するために設定やコマンドを実行する必要はありません。

以下に示すように、 posts という名前のデータベースにドキュメントを挿入したと仮定します-

> db.posts.insert(
{
   "post_text": "enjoy the mongodb articles on finddevguides",
   "tags": [
      "mongodb",
      "finddevguides"
   ]
}
WriteResult({ "nInserted" : 1 })

正規表現を使用する

次の正規表現クエリは、文字列 finddevguides を含むすべての投稿を検索します-

> db.posts.find({post_text:{$regex:"finddevguides"}}).pretty()
{
    "_id" : ObjectId("5dd7ce28f1dd4583e7103fe0"),
    "post_text" : "enjoy the mongodb articles on finddevguides",
    "tags" : [
        "mongodb",
        "finddevguides"
    ]
}
{
    "_id" : ObjectId("5dd7d111f1dd4583e7103fe2"),
    "post_text" : "enjoy the mongodb articles on finddevguides",
    "tags" : [
        "mongodb",
        "finddevguides"
    ]
}
>

同じクエリは次のように書くこともできます-

>db.posts.find({post_text:/finddevguides/})

大文字と小文字を区別しないで正規表現を使用する

検索で大文字と小文字を区別しないようにするには、 $ options パラメーターと値 $ i を使用します。 次のコマンドは、大文字か小文字かに関係なく、 finddevguides という単語を含む文字列を検索します-

>db.posts.find({post_text:{$regex:"finddevguides",$options:"$i"}})

このクエリから返される結果の1つは、次のドキュメントで、さまざまなケースで finddevguides という単語が含まれています-

{
   "_id" : ObjectId("53493d37d852429c10000004"),
   "post_text" : "hey! this is my post on finddevguides",
   "tags" : [ "finddevguides" ]
}

配列要素に正規表現を使用する

配列フィールドで正規表現の概念を使用することもできます。 これは、タグの機能を実装するときに特に重要です。 したがって、単語tutorial(tutorialまたはtutorialsまたはtutorialpointまたはtutorialphpのいずれか)で始まるタグを持つすべての投稿を検索する場合は、次のコードを使用できます-

>db.posts.find({tags:{$regex:"tutorial"}})

正規表現クエリの最適化

  • ドキュメントフィールドが*インデックス付き*の場合、クエリはインデックス付きの値を使用して正規表現と一致します。 これにより、コレクション全体をスキャンする正規表現と比較して、検索が非常に高速になります。
  • 正規表現が prefix expression である場合、すべての一致は特定の文字列文字で始まることを意味します。 たとえば、正規表現が ^ tut の場合、クエリは tut で始まる文字列のみを検索する必要があります。

RockMongoでの作業

RockMongoは、サーバー、データベース、コレクション、ドキュメント、インデックスなどを管理できるMongoDB管理ツールです。 ドキュメントの読み取り、書き込み、および作成のための非常にユーザーフレンドリーな方法を提供します。 これは、PHPおよびMySQL用のPHPMyAdminツールに似ています。

RockMongoをダウンロードする

RockMongoの最新バージョンは、https://github.com/iwind/rockmongoからダウンロードできます。

RockMongoのインストール

ダウンロードしたら、サーバーのルートフォルダーでパッケージを解凍し、抽出したフォルダーの名前を rockmongo に変更できます。 任意のWebブラウザーを開き、フォルダーrockmongoから index.php ページにアクセスします。 ユーザー名/パスワードとしてそれぞれadmin/adminを入力します。

RockMongoでの作業

これから、RockMongoで実行できる基本的な操作をいくつか見ていきます。

新しいデータベースの作成

新しいデータベースを作成するには、[データベース]タブをクリックします。 [新しいデータベースの作成]をクリックします。 次の画面で、新しいデータベースの名前を入力し、[作成]をクリックします。 左側のパネルに新しいデータベースが追加されます。

新しいコレクションを作成する

データベース内に新しいコレクションを作成するには、左側のパネルからそのデータベースをクリックします。 上部の[新しいコレクション]リンクをクリックします。 コレクションに必要な名前を指定します。 Is Capped、Size、およびMaxの他のフィールドについて心配する必要はありません。 *作成*をクリックします。 新しいコレクションが作成され、左側のパネルに表示されるようになります。

新しいドキュメントを作成する

新しいドキュメントを作成するには、ドキュメントを追加するコレクションをクリックします。 コレクションをクリックすると、そのコレクション内のすべてのドキュメントがリストに表示されます。 新しいドキュメントを作成するには、上部の[*挿入]リンクをクリックします。 ドキュメントのデータをJSONまたは配列形式で入力し、[保存]をクリックします。

データのエクスポート/インポート

コレクションのデータをインポート/エクスポートするには、そのコレクションをクリックしてから、トップパネルの*エクスポート/インポート*リンクをクリックします。 次の手順に従ってデータをzip形式でエクスポートし、同じzipファイルをインポートしてデータをインポートし直します。

MongoDB-GridFS

*GridFS* は、画像、オーディオファイル、ビデオファイルなどの大きなファイルを格納および取得するためのMongoDB仕様です。 ファイルを保存するのは一種のファイルシステムですが、そのデータはMongoDBコレクション内に保存されます。 GridFSには、ドキュメントサイズの上限である16MBを超えるファイルを保存する機能があります。

GridFSはファイルをチャンクに分割し、各データのチャンクをそれぞれ最大サイズ255kの個別のドキュメントに保存します。

GridFSは、デフォルトで2つのコレクション fs.files および fs.chunks を使用して、ファイルのメタデータとチャンクを保存します。 各チャンクは、一意の_id ObjectIdフィールドによって識別されます。 fs.filesは親ドキュメントとして機能します。 fs.chunksドキュメントの files_id フィールドは、チャンクをその親にリンクします。

以下は、fs.filesコレクションのサンプル文書です-

{
   "filename": "test.txt",
   "chunkSize": NumberInt(261120),
   "uploadDate": ISODate("2014-04-13T11:32:33.557Z"),
   "md5": "7b762939321e146569b07f72c62cca4f",
   "length": NumberInt(646)
}

ドキュメントは、ファイル名、チャンクサイズ、アップロード日、および長さを指定します。

以下は、fs.chunksドキュメントのサンプルドキュメントです-

{
   "files_id": ObjectId("534a75d19f54bfec8a2fe44b"),
   "n": NumberInt(0),
   "data": "Mongo Binary Data"
}

GridFSへのファイルの追加

次に、 put コマンドを使用して、GridFSを使用してmp3ファイルを保存します。 これには、MongoDBインストールフォルダーのbinフォルダーにある mongofiles.exe ユーティリティを使用します。

コマンドプロンプトを開き、MongoDBインストールフォルダのbinフォルダにあるmongofiles.exeに移動し、次のコードを入力します-

>mongofiles.exe -d gridfs put song.mp3

ここで、 gridfs は、ファイルが保存されるデータベースの名前です。 データベースが存在しない場合、MongoDBはその場で自動的に新しいドキュメントを作成します。 Song.mp3は、アップロードされたファイルの名前です。 データベース内のファイルのドキュメントを表示するには、検索クエリを使用することができます-

>db.fs.files.find()

上記のコマンドは、次のドキュメントを返しました-

{
   _id: ObjectId('534a811bf8b4aa4d33fdf94d'),
   filename: "song.mp3",
   chunkSize: 261120,
   uploadDate: new Date(1397391643474), md5: "e4f53379c909f7bed2e9d631e15c1c41",
   length: 10401959
}

また、以前のクエリで返されたドキュメントIDを使用して、次のコードで保存されたファイルに関連するfs.chunksコレクションに存在するすべてのチャンクを見ることができます-

>db.fs.chunks.find({files_id:ObjectId('534a811bf8b4aa4d33fdf94d')})

私の場合、クエリは40個のドキュメントを返しました。つまり、mp3ドキュメント全体が40のデータチャンクに分割されました。

MongoDB-上限付きコレクション

  • キャップ付きコレクション*は、挿入順序に従う固定サイズの循環コレクションであり、作成、読み取り、削除操作の高いパフォーマンスをサポートします。 循環とは、コレクションに割り当てられた固定サイズが使い果たされると、明示的なコマンドを提供せずにコレクション内の最も古いドキュメントの削除を開始することを意味します。

更新によりドキュメントサイズが大きくなる場合、キャップ付きコレクションはドキュメントの更新を制限します。 上限のあるコレクションはドキュメントをディスクストレージの順序で保存するため、ドキュメントサイズがディスクに割り当てられたサイズを増加させないようにします。 上限付きコレクションは、ログ情報、キャッシュデータ、またはその他の大量のデータを保存するのに最適です。

キャップ付きコレクションの作成

キャップ付きコレクションを作成するには、通常のcreateCollectionコマンドを使用しますが、 capped オプションを true として使用し、コレクションの最大サイズをバイト単位で指定します。

>db.createCollection("cappedLogCollection",{capped:true,size:10000})

コレクションのサイズに加えて、 max パラメータを使用してコレクション内のドキュメントの数を制限することもできます-

>db.createCollection("cappedLogCollection",{capped:true,size:10000,max:1000})

あなたがコレクションがキャップされているかどうかを確認したい場合は、次の isCapped コマンドを使用します-

>db.cappedLogCollection.isCapped()

あなたがキャップに変換することを計画している既存のコレクションがある場合は、次のコードでそれを行うことができます-

>db.runCommand({"convertToCapped":"posts",size:10000})

このコードは、既存のコレクション*投稿*をキャップ付きコレクションに変換します。

キャップ付きコレクションのクエリ

デフォルトでは、キャップ付きコレクションの検索クエリは挿入結果で結果を表示します。 しかし、ドキュメントを逆順で取得したい場合は、次のコードに示すように sort コマンドを使用します-

>db.cappedLogCollection.find().sort({$natural:-1})

知っておく価値のある上限付きコレクションに関するその他の重要な点はほとんどありません-

  • 上限付きコレクションからドキュメントを削除することはできません。
  • キャップ付きコレクションには、_idフィールドにもデフォルトインデックスはありません。
  • 新しいドキュメントを挿入する際、MongoDBはディスク上の新しいドキュメントに対応する場所を実際に探す必要はありません。 コレクションの末尾に新しいドキュメントを盲目的に挿入できます。 これにより、上限付きコレクションへの挿入操作が非常に高速になります。
  • 同様に、ドキュメントの読み取り中、MongoDBはディスクに存在するのと同じ順序でドキュメントを返します。 これにより、読み取り操作が非常に高速になります。

MongoDB-自動インクリメントシーケンス

MongoDBには、SQLデータベースのようなすぐに使用可能な自動インクリメント機能はありません。 デフォルトでは、ドキュメントを一意に識別するための主キーとして _id フィールドに12バイトのObjectIdを使用します。 ただし、_idフィールドに、ObjectId以外の自動インクリメント値を持たせたいシナリオがあるかもしれません。

これはMongoDBのデフォルトの機能ではないため、MongoDBのドキュメントで提案されている counters コレクションを使用して、プログラムでこの機能を実現します。

カウンターコレクションの使用

次の*製品*ドキュメントを検討してください。 _idフィールドは、1,2,3,4からnまでの auto-incremented integer sequence にする必要があります。

{
  "_id":1,
  "product_name": "Apple iPhone",
  "category": "mobiles"
}

このために、すべてのシーケンスフィールドの最後のシーケンス値を追跡する counters コレクションを作成します。

>db.createCollection("counters")

ここで、キーとして productid を使用して次のドキュメントをcountersコレクションに挿入します-

> db.counters.insert({
    "_id":"productid",
    "sequence_value": 0
})
WriteResult({ "nInserted" : 1 })
>

フィールド sequence_value は、シーケンスの最後の値を追跡します。

次のコードを使用して、このシーケンスドキュメントをカウンタコレクションに挿入します-

>db.counters.insert({_id:"productid",sequence_value:0})

JavaScript関数の作成

次に、入力としてシーケンス名を取得し、シーケンス番号を1増やして、更新されたシーケンス番号を返す関数 getNextSequenceValue を作成します。 この場合、シーケンス名は productid です。

>function getNextSequenceValue(sequenceName){
   var sequenceDocument = db.counters.findAndModify({
      query:{_id: sequenceName },
      update: {$inc:{sequence_value:1}},
      new:true
   });
   return sequenceDocument.sequence_value;
}

JavaScript関数を使用する

ここで、関数getNextSequenceValueを使用して、新しいドキュメントを作成し、返されたシーケンス値をドキュメントの_idフィールドとして割り当てます。

次のコードを使用して2つのサンプル文書を挿入します-

>db.products.insert({
   "_id":getNextSequenceValue("productid"),
   "product_name":"Apple iPhone",
   "category":"mobiles"
})
>db.products.insert({
   "_id":getNextSequenceValue("productid"),
   "product_name":"Samsung S3",
   "category":"mobiles"
})

ご覧のとおり、getNextSequenceValue関数を使用して_idフィールドの値を設定しました。

機能を確認するには、findコマンドを使用してドキュメントを取得します-

>db.products.find()

上記のクエリは、自動インクリメントされた_idフィールドを持つ次のドキュメントを返しました-

{ "_id" : 1, "product_name" : "Apple iPhone", "category" : "mobiles"}
{ "_id" : 2, "product_name" : "Samsung S3", "category" : "mobiles" }

Mongodb-questions-answers