開発者向けのMongoDb。 週2

良い時間、Habr。 このトピックは、10genのオンラインコースM101の資料に基づいた一連の記事の続きです。 2週目は最も波乱に富んだものの1つであるため、2つの記事に分かれます。



すぐに明確にします-この記事で説明されているのは、mongoバージョン2.6に対して有効です。 いずれにせよ、読み返すことをお勧めします。 ドキュメント

時間があれば、コースをご覧ください



サイクルの最初の記事



この投稿では、CRUD操作について説明します。 組み込みシェルのjsの例が示されており、最初の記事のように他の言語との些細さのために、例は移植されていません。



Mongoは、CRUD操作を実行するためのメソッドの完全なセットを提供します。





mongo-driversのすべてのCRUDメソッドは、プログラミング言語の関数(メソッド)であり、個別の言語(hello sql)の式を作成する手段ではありません。 MongoDbには、メソッドコールを提供し、作業の結果を返すTCP上で動作する特別なプロトコルがあります。

たとえば、シェルで要求する



db.users.findOne({name:"Alice"})
      
      







データベースオブジェクトへのリンクを参照し、そのユーザー属性を要求し、検索条件を構成するオブジェクトを渡すfindOneメソッドを(コレクションインターフェイスから)呼び出します

SQL文字列ではなく、オブジェクトとそのメソッドを常に使用しています。



Shell MongoDbは、組み込みドライバーを備えたインタラクティブなJSインタープリターです。 入力すると、バージョン情報と現在のデータベースの名前が与えられます。 ターゲット以外のデータベースでのアクションを防ぐためにこの情報に注意を払う価値があり、バージョンの新鮮さを追跡することは場違いではありません。 どのバージョンのシェルも、どのバージョンのmongoサーバーでも使用できますが、古いバージョンのシェルの一部の新しい機能はサポートされない場合があります。

シェルはインタープリターであるため、さまざまな有効なjsコンストラクトを使用して作業を促進できます。



開発段階でよく使用される小さな例を次に示します-インデックスを削除せずにすべてのコレクションをクリアします

  var list=db.getCollectionNames(); for (var i = 0; i < list.length; i++) { if (list[i]!="system.indexes") db.getCollection(list[i]).remove(); }
      
      







シェルには、ほとんどのLinuxユーザーになじみのある便利な機能がいくつかあります。



上矢印 / 下矢印 -チームの履歴をめくる

ctrl + A / Home-行の先頭に移動

ctrl + E / End-行末に移動します

Ctrl + B / 左矢印 -カーソルを左に移動

ctrl + F / 右矢印 -カーソルを右に移動

タブオートコンプリート関数名とコレクション名。



リクエストで何が起こるかをよりよく理解するために、Mongoのデータの内部表現について詳しく説明する価値があります。



MongoはBSON形式(バイナリJSONの頭字語)を使用します。 Webサイトbsonspec.orgで詳細な仕様に慣れることができます。 要求を作成するとき、ドライバーはBSONで要求オブジェクト(たとえば、選択基準)をエンコードし、応答を処理するときに、反対の操作を実行します。

使用されるプログラミング言語に応じて、データは表示可能な言語のエンティティにマッピングされます。



主なことは、そのようなエンティティを取得してデータベースに保存できることです。 Mongoは、このデータのバイナリ表現を使用します。

BSON形式は、JSON +と同じデータ型に加えて、内部使用のためのいくつかの型をサポートします。



ドライバーはいずれにせよ、BSONで使用されるすべてのタイプをサポートし、使用される言語のデータはサポートされるタイプのいずれかに変換されます。 型のセットが限られている言語で作業する場合、これを考慮する必要があります。



すべての通常のコレクションには_id属性があります。これは一意の主キーであり、後で異常なコレクションについて説明します。 ドキュメントを削除して新しいドキュメントに挿入しない限り、変更できません。

_idが明示的に設定されていない場合、オブジェクトを作成するときに、追加のエントロピー値を使用して、かなりトリッキーなアルゴリズムに従って形成されます



+ + + , .







場合によっては、たとえばユーザーデータを格納するコレクションに対して、_idを明示的に定義する方が便利な場合があります。ユーザーのログインを識別子として使用できます。 識別子には、サポートされている任意のデータ型を使用できます。



前回の記事では、コレクション内の新しいドキュメントの作成について既に検討しました。 次に、それらを取り戻す方法を検討します。

フェッチするためのfind()メソッドがあります。 コレクションの1つの要素が必要な場合は、findOne()を使用すると便利です。



findOne(criteria,fields)

criteria - . ( ).

fields - , , - . - true







2番目のドキュメントには1つの機能があります-_idフィールドは、返されるべきでないことが明示的に示されていない限り、常に返されます。



彼らが言うように-それは百回聞くよりも一度見た方が良いです

 //      > db.users.insert({name:"Woody","role":"sheriff",age:"unknown"}) > db.users.insert({name:"Buzz","role":"space ranger",age:"unknown"}) //  ,     name. .    -      > db.users.findOne({name:"Woody"}) { "_id" : ObjectId("509ffa90cc922c3538cd1ce1"), "name" : "Woody", "role" : "sheriff", "age" : "unknown" } //     > db.users.findOne({name:"Woody"}, {name:true}) { "_id" : ObjectId("509ffa90cc922c3538cd1ce1"), "name" : "Woody" } //  ,     ,  - .    ,     //      ,   .          // ,       > db.users.findOne({name:"Woody"},{name:1,role:1,_id:0}) { "name" : "Woody", "role" : "sheriff" } >
      
      







find()を使用して、複雑な検索条件の作成に使用される演算子を考えてみましょう。



ところで、私はまだ忘れていません-あなたが大きなデータセットを受け取った場合、それらの限られた部分がシェルに表示され(デフォルトでは20)、次の部分を取得するためにそれを入力できます。 実際には、ドライバーだけでなく(シェルだけでなく)。 要求への応答では、データを受信しません。 彼はそれらの上にカーソルを置きます。 カーソルはしばらくの間(デフォルトでは10分間)サーバーに保存され、その後削除されます。



リクエストは、カーソルからの読み取りを開始したときにのみ実際に実行されます。 その後、データを受け取ります。 これに先立ち、アクションは実行されません。





Find()には、findOneとまったく同じパラメーターがあります

find(criteria,fields)







等価検索のケースについてはすでに検討しました。 より複雑な条件を作成するために、キーは比較メソッドとそれらのパラメーターを含むドキュメントで示されます。



$ gt-、その他

$ gte-以上

$ lt-少ない

$ lte-より小さいか等しい



これは、シェルでは20歳以上30歳未満のすべてのユーザーのサンプルのリクエストのように見えます。バランスは100です。

 db.users.find({age:{$gt:20,$lt:30},balance:{$gte:100}});
      
      





ご覧のとおり、基準ドキュメントのキーの数は任意です。



同等ではない比較演算子を文字列に適用できます

 db.people.find({name:{$lt:"D"}})
      
      







Mongoはロケールについて何も知りません-utf文字コードが比較されます。 Mongoはダイアグラムレスであるため、同じコレクションの異なるドキュメントの同じキーに異なるタイプのデータを含めることができることに注意してください。 Mongoの比較操作は入力されているため、intという名前のドキュメントをコレクションに追加した場合、上記の検索クエリは検索結果にそれを返しません。 一般に、1つのキーにさまざまなタイプのデータを保存することは可能ですが、選択が複雑になるためお勧めできません。



ソートおよび比較演算子では大文字と小文字が区別されます

比較演算子の使用は重要ではありません。



Mongoでは、ドキュメントに格納されている値だけでなく、その構造とデータ型にも基づいてクエリを作成できます。



 db.people.find({hobby:{$exists:true}})
      
      





$ exists-ドキュメント要素の存在



特定のドキュメント要素のタイプに基づいてクエリを作成できます



$ type-BSON要素の型と指定された型の等価性を確認します

 db.people.find({name:{$type:2}})
      
      







$ regex-特定のPCREに準拠しているかどうかアイテムを確認します

 //     email     nail.ru db.users.find("email":{$regex:"mail.ru$"}})
      
      







来週、パフォーマンスの問題を考慮する正規表現について詳しく説明します。 人々が速度の低下を恐れていないことは注目に値します。たとえば、正規表現の検索^ Aは、エンジンによって範囲[A、B)のクエリに音訳されます



条件を作る方法を見てみましょうOR

論理ORを使用して複数の条件を組み合わせるには、プレフィックス演算子$または

$または:[条件の配列]



 db.users.find({$or:[{age:{$gt:10}},{name:{$regex:"^A"}}]});
      
      







シェルでより複雑なクエリをコンパイルする場合、組み込みの要素の境界線の強調表示の有用性が大幅に向上することに注意してください。



論理積の場合、$ and演算子が使用されます。 これは$または構文とまったく同じであり、これ以上詳しく説明する理由はありません。 通常、リクエストはより簡単に表現できるため、この演算子はほとんど使用されないことに注意してください



配列を操作する



配列のクエリでは、mongoはポリモーフィックです

 db.users.find({favorites:"beer"})
      
      





お気に入り文書に文字列がある場合、それが同等である場合は選択に分類され、お気に入りが配列である場合、要素のいずれかが同等である場合は選択に含まれます。



この動作は、Mongoイディオムでは非常に一般的です。

Mongoは配列の再帰的な列挙を実行せず、上位レベルのみが表示されます。



配列を検索するための特定の演算子もいくつかあります。

$ all-配列内のすべてのリストされた値を含む要素を選択します

 $db.users.find(favorites:{$all:{"beer","milk"}})
      
      







$ inは、Sikuel演算子INに類似しています。 配列にリストされている選択された要素の値を持つすべてのドキュメントを返します。 この演算子を使用するクエリは、常に$または



ドット付き記録(ドット表記)




前の例では、文字列、数字、配列を含むドキュメントを使用しました。 積み上げられたオブジェクトに乗り出す時が来ました。

Mongoは、添付ドキュメントの内部要素に対してクエリを作成できる特別な構文をサポートしています。



 db.users.find("email.work":{$regex:"mail.ru$"}})
      
      





ドット表記の目的は、添付文書の要素を表示することです。 この構文は、配列の特定の要素にアクセスするためにも使用できます。



続行するには...



All Articles