目次
単一キー インデックス
結合インデックスは、インデックスに複数のフィールドが存在することを意味します。以下の
配列インデックスは、配列フィールドのインデックス (複数値インデックスとも呼ばれます)。テストするために、users コレクション内のデータが以下のいくつかの配列フィールドに追加されます。
元の users コレクションに地理情報を追加します。
TTL の完全なスペルは、time to です。 live は、主に期限切れデータの自動削除に使用されます。この種のインデックスを使用するには、ドキュメント内で時間型フィールドを宣言する必要があります。また、このフィールドの TTL インデックスを作成するときに、次のことも行う必要があります。
条件索引
稀疏索引
文本索引
唯一索引
ホームページ データベース モンゴDB MongoDB の豊富なインデックス タイプについて話しましょう

MongoDB の豊富なインデックス タイプについて話しましょう

Feb 17, 2022 am 10:58 AM
mongodb インデックスの種類

この記事では、MongoDB を理解し、MongoDB の豊富なインデックス タイプを紹介します。皆様のお役に立てれば幸いです。

MongoDB の豊富なインデックス タイプについて話しましょう

MongoDB のインデックスと MySql のインデックスの機能は、機能と最適化原則の点で基本的に似ています。 MySqlインデックス タイプは基本的に次のように区別できます。

  • 単一キー インデックス - ジョイント インデックス
  • 主キー インデックス (クラスター化インデックス) - 非主キー インデックス (非クラスター化インデックス)

MongoDB には、これらの基本的な分類に加えて、配列インデックス | スパース インデックス | 地理空間インデックス | TTL インデックスなどの特殊なインデックス タイプもあります。 etc.

以下のテストの便宜上、スクリプトを使用して次のデータを挿入します

for(var i = 0;i < 100000;i++){
    db.users.insertOne({
        username: "user"+i,
        age: Math.random() * 100,
        sex: i % 2,
        phone: 18468150001+i
    });
}
ログイン後にコピー

単一キー インデックス

単一キー インデックスの意味最も基本的なインデックスであるインデックス付きフィールドが 1 つだけであることを示します。Method.

コレクション内の

username フィールドを使用して、単一のキー インデックスを作成します。MongoDBこのインデックスには自動的に username_1

db.users.createIndex({username:1})
&#39;username_1&#39;
ログイン後にコピー

という名前が付けられます。インデックスを作成した後、

username フィールドを使用してクエリ プランを確認します。stage IXSCAN (インデックス スキャンが使用されることを意味します)

db.users.find({username:"user40001"}).explain()
{ 
   queryPlanner: 
   { 
     winningPlan: 
     { 
        ......
        stage: &#39;FETCH&#39;,
        inputStage: 
        { 
           stage: &#39;IXSCAN&#39;,
           keyPattern: { username: 1 },
           indexName: &#39;username_1&#39;,
           ......
        } 
     }
     rejectedPlans: [] ,
   },
   ......
   ok: 1 
}
ログイン後にコピー

インデックス最適化の原則の中で、非常に重要な原則は、インデックスはカーディナリティの高いフィールド上に構築されるべきであるということです。いわゆるカーディナリティは次のとおりです。フィールド内の非反復値の数、つまり

users を作成するとき。収集中に表示される年齢の値が 0-99 の場合、 age フィールドには 100 個の一意の値が含まれます。つまり、age フィールドのベースは 100 です。 sex フィールドには 2 つの値のみが含まれます 0 | 1、つまり、sex フィールドの基数は 2 であり、かなり低い基数です。この場合、インデックスの効率は高くなく、インデックスの失敗につながります。 # 実行プランをクエリするための

sex

フィールド インデックスを構築しましょう。クエリが関連インデックスなしでフル テーブル スキャンを実行したことがわかります。<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>db.users.createIndex({sex:1}) &amp;#39;sex_1&amp;#39; db.users.find({sex:1}).explain() { queryPlanner: { ...... winningPlan: { stage: &amp;#39;COLLSCAN&amp;#39;, filter: { sex: { &amp;#39;$eq&amp;#39;: 1 } }, direction: &amp;#39;forward&amp;#39; }, rejectedPlans: [] }, ...... ok: 1 }</pre><div class="contentsignin">ログイン後にコピー</div></div>

ジョイント インデックス

結合インデックスは、インデックスに複数のフィールドが存在することを意味します。以下の

age## を使用します。# と

sex は、2 つのフィールド

db.users.createIndex({age:1,sex:1})
&#39;age_1_sex_1&#39;
ログイン後にコピー
## を持つインデックスを作成します# 次に、これら 2 つのフィールドを使用してクエリを実行し、実行計画を確認し、このインデックスを正常に実行します <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>db.users.find({age:23,sex:1}).explain() { queryPlanner: { ...... winningPlan: { stage: &amp;#39;FETCH&amp;#39;, inputStage: { stage: &amp;#39;IXSCAN&amp;#39;, keyPattern: { age: 1, sex: 1 }, indexName: &amp;#39;age_1_sex_1&amp;#39;, ....... indexBounds: { age: [ &amp;#39;[23, 23]&amp;#39; ], sex: [ &amp;#39;[1, 1]&amp;#39; ] } } }, rejectedPlans: [], }, ...... ok: 1 }</pre><div class="contentsignin">ログイン後にコピー</div></div>

配列インデックス

配列インデックスは、配列フィールドのインデックス (複数値インデックスとも呼ばれます)。テストするために、users コレクション内のデータが以下のいくつかの配列フィールドに追加されます。

db.users.updateOne({username:"user1"},{$set:{hobby:["唱歌","篮球","rap"]}})
......
ログイン後にコピー

配列を作成するインデックスを作成し、その実行プランを表示します。isMultiKey: true は、使用されるインデックスが複数値のインデックスであることを意味します。

db.users.createIndex({hobby:1})
&#39;hobby_1&#39;

db.users.find({hobby:{$elemMatch:{$eq:"钓鱼"}}}).explain()
{ 
   queryPlanner: 
   { 
     ......
     winningPlan: 
     { 
        stage: &#39;FETCH&#39;,
        filter: { hobby: { &#39;$elemMatch&#39;: { &#39;$eq&#39;: &#39;钓鱼&#39; } } },
        inputStage: 
        { 
           stage: &#39;IXSCAN&#39;,
           keyPattern: { hobby: 1 },
           indexName: &#39;hobby_1&#39;,
           isMultiKey: true,
           multiKeyPaths: { hobby: [ &#39;hobby&#39; ] },
           ......
           indexBounds: { hobby: [ &#39;["钓鱼", "钓鱼"]&#39; ] } } 
         },
     rejectedPlans: [] 
  },
  ......
  ok: 1 
}
ログイン後にコピー

配列インデックスは他のインデックスと比較されます。一般的に、インデックス エントリは、たとえば、各ドキュメントの hobby 配列の平均

size

が 10 である場合、このコレクションの hobby 配列インデックスは次のようになります。 結合配列インデックス

結合配列インデックスとは、配列フィールドを含む結合インデックスです。は 1 つのインデックスをサポートしません。複数の配列フィールドが含まれます。つまり、インデックス内に存在できる配列フィールドは最大 1 つです。これは、インデックス エントリの爆発的な増加を避けるためです。インデックス内に 2 つの配列フィールドがあると仮定すると、その数はインデックス エントリの数は、通常のインデックスの n* になります。m 倍

地理空間インデックス

元の users コレクションに地理情報を追加します。

for(var i = 0;i < 100000;i++){
    db.users.updateOne(
    {username:"user"+i},
    {
        $set:{
            location:{
                type: "Point",
                coordinates: [100+Math.random() * 4,40+Math.random() * 3]
            }
        }
    });
}
ログイン後にコピー

2 番目の次元空間インデックスの作成 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>db.users.createIndex({location:&quot;2dsphere&quot;}) &amp;#39;location_2dsphere&amp;#39; //查询500米内的人 db.users.find({ location:{ $near:{ $geometry:{type:&quot;Point&quot;,coordinates:[102,41.5]}, $maxDistance:500 } } })</pre><div class="contentsignin">ログイン後にコピー</div></div>地理空間インデックスの

type

には、

Ponit(point)

| を含むものが多数あります。 LineString(line) | Polygon (Polygon)etcTTL インデックス

TTL の完全なスペルは、time to です。 live は、主に期限切れデータの自動削除に使用されます。この種のインデックスを使用するには、ドキュメント内で時間型フィールドを宣言する必要があります。また、このフィールドの TTL インデックスを作成するときに、次のことも行う必要があります。

expireAfterSecondsを設定します

作成完了後の有効期限の単位は秒ですMongoDBコレクション内のデータは定期的にチェックされます。表示されるタイミング:<div class="math math-display"><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics>##現在時刻<mrow><mtext>−</mtext><mo>T</mo><mi>T</mi> <mi>L</mi><mi>インデックス フィールド時間</mi><mtext>></mtext><mo>e</mo><mi>xx</mi><mi>p</mi><mi>i</mi> <mi>r</mi><mi>e</mi><mi>A</mi><mi>f</mi><mi>t</mi><mi>e</mi><mi>r</mi><mi>S</mi><mi>r</mi><mi>c</mi><mi>o</mi><mi>n</mi><mi>d</mi><mi>s</mi><mi></mi>現在時刻 - TTL インデックス フィールド時間>expireAfterSrconds</mrow><annotation encoding="application/x-tex"></annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base">##when<span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span>before<span class="mord cjk_fallback"></span> <span class="mord cjk_fallback"></span>间<span class="mord cjk_fallback"></span><span class="mord cjk_fallback"></span>−<span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span>##T<span class="base"><span class="strut" style="height:0.72243em;vertical-align:-0.0391em;">T</span> <span class="mord mathnormal" style="margin-right:0.13889em;">#L</span><span class="mord mathnormal" style="margin-right:0.13889em;">index</span><span class="mord mathnormal">cite</span><span class="mord cjk_fallback">字</span><span class="mord cjk_fallback">セクション</span><span class="mord cjk_fallback">時間</span><span class="mord cjk_fallback">インター</span><span class="mord cjk_fallback"></span>#><span class="mord cjk_fallback"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"></span><span class="mspace" style="margin-right:0.2777777777777778em;">e</span>##x</span><span class="base">p<span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span>i<span class="mord mathnormal"></span>r<span class="mord mathnormal"></span>e<span class="mord mathnormal"></span>A<span class="mord mathnormal"></span>f<span class="mord mathnormal" style="margin-right:0.02778em;"></span>t<span class="mord mathnormal"></span>e<span class="mord mathnormal"> </span>r<span class="mord mathnormal" style="margin-right:0.10764em;"></span>S<span class="mord mathnormal"></span>r<span class="mord mathnormal"></span>c<span class="mord mathnormal" style="margin-right:0.02778em;"></span>o<span class="mord mathnormal" style="margin-right:0.05764em;"></span>n<span class="mord mathnormal" style="margin-right:0.02778em;"></span>d<span class="mord mathnormal"></span> s<span class="mord mathnormal"></span><span class="mord mathnormal"></span><span class="mord mathnormal"></span><p><code>MongoDB将会自动将这些文档删除,这种索引还有以下这些要求:

  • TTL索引只能有一个字段,没有联合TTL索引
  • TTL不能用于固定集合
  • TTL索引是逐个遍历后,发现满足删除条件会使用delete函数删除,效率并不高

首先在我们文档上增减一个时间字段

for(var i = 90000;i < 100000;i++){
    db.users.updateOne(
    {username:"user"+i},
    {
        $set:{
            createdDate:new Date()
        }
    });
}
ログイン後にコピー

创建一个TTL索引并且设定过期时间为60s,待过60s后查询,会发现这些数据已经不存在

db.users.createIndex({createdDate:1},{expireAfterSeconds:60})
&#39;createdDate_1&#39;
ログイン後にコピー

另外还可以用CollMod命令更改TTL索引的过期时间

db.runCommand({
  collMod:"users",
  index:{
    keyPattern:{createdDate:1},
    expireAfterSeconds:120
  }
})

{ expireAfterSeconds_old: 60, expireAfterSeconds_new: 120, ok: 1 }
ログイン後にコピー

条件索引

条件索引也叫部分索引(partial),只对满足条件的数据进行建立索引.

只对50岁以上的user进行建立username_1索引,查看执行计划会发现isPartial这个字段会变成true

db.users.createIndex({username:1},{partialFilterExpression:{
    age:{$gt:50}
  }})
&#39;username_1&#39;

db.users.find({$and:[{username:"user4"},{age:60}]}).explain()
{ 
  queryPlanner: 
  { 
     ......
     winningPlan: 
     { 
        stage: &#39;FETCH&#39;,
        filter: { age: { &#39;$eq&#39;: 60 } },
        inputStage: 
        { 
           stage: &#39;IXSCAN&#39;,
           keyPattern: { username: 1 },
           indexName: &#39;username_1&#39;,
           ......
           isPartial: true,
           ......
         } 
     },
     rejectedPlans: [] 
  },
  ......
  ok: 1 
}
ログイン後にコピー

稀疏索引

一般的索引会根据某个字段为整个集合创建一个索引,即使某个文档不存这个字段,那么这个索引会把这个文档的这个字段当作null建立在索引当中.

稀疏索引不会对文档中不存在的字段建立索引,如果这个字段存在但是为null时,则会创建索引.

下面给users集合中的部分数据创建稀疏索引

for(var i = 5000;i < 10000;i++){
  if(i < 9000){
    db.users.updateOne(
      {username:"user"+i},
      { $set:{email:(120000000+i)+"@qq.email"}}
    )
  }else{
    db.users.updateOne(
      {username:"user"+i},
      { $set:{email:null}}
    )
  }
}
ログイン後にコピー

当不建立索引使用{email:null}条件进行查询时,我们会发现查出来的文档包含没有email字段的文档

db.users.find({email:null})
{ 
  _id: ObjectId("61bdc01ba59136670f6536fd"),
  username: &#39;user0&#39;,
  age: 64.41483801726282,
  sex: 0,
  phone: 18468150001,
  location: 
  { 
    type: &#39;Point&#39;,
    coordinates: [ 101.42490900320335, 42.2576650823515 ] 
  } 
}
......
ログイン後にコピー

然后对email这个字段创建一个稀疏索引使用{email:null}条件进行查询,则发现查询来的文档全部是email字段存在且为null的文档.

db.users.createIndex({email:1},{sparse:true});
&#39;email_1&#39;

db.users.find({email:null}).hint({email:1})
{ 
  _id: ObjectId("61bdc12ca59136670f655a25"),
  username: &#39;user9000&#39;,
  age: 94.18397576757012,
  sex: 0,
  phone: 18468159001,
  hobby: [ &#39;钓鱼&#39;, &#39;乒乓球&#39; ],
  location: 
  { 
    type: &#39;Point&#39;,
    coordinates: [ 101.25903151863596, 41.38450145025062 ] 
  },
  email: null 
}
......
ログイン後にコピー

文本索引

文本索引将建立索引的文档字段先进行分词再进行检索,但是目前还不支持中文分词.

下面增加两个文本字段,创建一个联合文本索引

db.blog.insertMany([
  {title:"hello world",content:"mongodb is the best database"},
  {title:"index",content:"efficient data structure"}
])

//创建索引
db.blog.createIndex({title:"text",content:"text"})
&#39;title_text_content_text&#39;
//使用文本索引查询
db.blog.find({$text:{$search:"hello data"}})
{ 
  _id: ObjectId("61c092268c4037d17827d977"),
  title: &#39;index&#39;,
  content: &#39;efficient data structure&#39; 
},
{ 
  _id: ObjectId("61c092268c4037d17827d976"),
  title: &#39;hello world&#39;,
  content: &#39;mongodb is the best database&#39; 
}
ログイン後にコピー

唯一索引

唯一索引就是在建立索引地字段上不能出现重复元素,除了单字段唯一索引还有联合唯一索引以及数组唯一索引(即数组之间不能有元素交集 )

//对title字段创建唯一索引
db.blog.createIndex({title:1},{unique:true})
&#39;title_1&#39;
//插入一个已经存在的title值
db.blog.insertOne({title:"hello world",content:"mongodb is the best database"})
MongoServerError: E11000 duplicate key error collection: mock.blog index: title_1 dup key: { : "hello world" }
//查看一下执行计划,isUnique为true
db.blog.find({"title":"index"}).explain()
{ 
  queryPlanner: 
  { 
     ......
     winningPlan: 
     { 
        stage: &#39;FETCH&#39;,
        inputStage: 
        { 
           stage: &#39;IXSCAN&#39;,
           keyPattern: { title: 1 },
           indexName: &#39;title_1&#39;,
           isMultiKey: false,
           multiKeyPaths: { title: [] },
           isUnique: true,
           ......
         } 
     },
     rejectedPlans: [] 
  },
  .......
  ok: 1 
}
ログイン後にコピー

相关视频教程推荐:《MongoDB教程

以上がMongoDB の豊富なインデックス タイプについて話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

navicat の有効期限が切れた場合の対処方法 navicat の有効期限が切れた場合の対処方法 Apr 23, 2024 pm 12:12 PM

Navicat の有効期限の問題を解決するには、ライセンスを更新する、自動更新を無効にする、Navicat プレミアム エッセンシャルの無料バージョンを使用する、などがあります。

navicat を mongodb に接続する方法 navicat を mongodb に接続する方法 Apr 24, 2024 am 11:27 AM

Navicat を使用して MongoDB に接続するには、次の手順を実行する必要があります: Navicat をインストールする MongoDB 接続を作成します: a. 接続名、ホスト アドレス、およびポートを入力します b. 認証情報を入力します (必要な場合) SSL 証明書を追加します (必要な場合) 接続を確認します接続を保存する

net4.0の用途は何ですか net4.0の用途は何ですか May 10, 2024 am 01:09 AM

.NET 4.0 はさまざまなアプリケーションの作成に使用され、オブジェクト指向プログラミング、柔軟性、強力なアーキテクチャ、クラウド コンピューティングの統合、パフォーマンスの最適化、広範なライブラリ、セキュリティ、スケーラビリティ、データ アクセス、モバイルなどの豊富な機能をアプリケーション開発者に提供します。開発サポート。

サーバーレスアーキテクチャでのJava関数とデータベースの統合 サーバーレスアーキテクチャでのJava関数とデータベースの統合 Apr 28, 2024 am 08:57 AM

サーバーレス アーキテクチャでは、Java 関数をデータベースと統合して、データベース内のデータにアクセスして操作できます。主な手順には、Java 関数の作成、環境変数の構成、関数のデプロイ、および関数のテストが含まれます。これらの手順に従うことで、開発者はデータベースに保存されているデータにシームレスにアクセスする複雑なアプリケーションを構築できます。

INNODBのクラスターインデックスと非クラスターインデックス(セカンダリインデックス)の違い。 INNODBのクラスターインデックスと非クラスターインデックス(セカンダリインデックス)の違い。 Apr 02, 2025 pm 06:25 PM

クラスター化されたインデックスと非クラスター化されたインデックスの違いは次のとおりです。1。クラスター化されたインデックスは、インデックス構造にデータを保存します。これは、プライマリキーと範囲でクエリするのに適しています。 2.非クラスター化されたインデックスストアは、インデックスキー値とデータの行へのポインターであり、非プリマリーキー列クエリに適しています。

さまざまなタイプのMySQLインデックス(Bツリー、ハッシュ、フルテキスト、空間)を説明します。 さまざまなタイプのMySQLインデックス(Bツリー、ハッシュ、フルテキスト、空間)を説明します。 Apr 02, 2025 pm 07:05 PM

MySQLは、Bツリー、ハッシュ、フルテキスト、および空間の4つのインデックスタイプをサポートしています。 1.B-Treeインデックスは、等しい値検索、範囲クエリ、ソートに適しています。 2。ハッシュインデックスは、等しい値検索に適していますが、範囲のクエリとソートをサポートしていません。 3.フルテキストインデックスは、フルテキスト検索に使用され、大量のテキストデータの処理に適しています。 4.空間インデックスは、地理空間データクエリに使用され、GISアプリケーションに適しています。

DebianでMongoDB自動拡張を構成する方法 DebianでMongoDB自動拡張を構成する方法 Apr 02, 2025 am 07:36 AM

この記事では、自動拡張を実現するためにDebianシステムでMongodbを構成する方法を紹介します。主な手順には、Mongodbレプリカセットとディスクスペース監視のセットアップが含まれます。 1。MongoDBのインストール最初に、MongoDBがDebianシステムにインストールされていることを確認してください。次のコマンドを使用してインストールします。sudoaptupdatesudoaptinstinstall-yymongodb-org2。mongodbレプリカセットMongodbレプリカセットの構成により、自動容量拡張を達成するための基礎となる高可用性とデータ冗長性が保証されます。 Mongodbサービスを開始:Sudosystemctlstartmongodsudosys

DebianでMongodbの高可用性を確保する方法 DebianでMongodbの高可用性を確保する方法 Apr 02, 2025 am 07:21 AM

この記事では、Debianシステムで非常に利用可能なMongoDBデータベースを構築する方法について説明します。データのセキュリティとサービスが引き続き動作し続けるようにするための複数の方法を探ります。キー戦略:レプリカセット:レプリカセット:レプリカセットを使用して、データの冗長性と自動フェールオーバーを実現します。マスターノードが失敗すると、レプリカセットが自動的に新しいマスターノードを選択して、サービスの継続的な可用性を確保します。データのバックアップと回復:MongoDumpコマンドを定期的に使用してデータベースをバックアップし、データ損失のリスクに対処するために効果的な回復戦略を策定します。監視とアラーム:監視ツール(プロメテウス、グラファナなど)を展開して、MongoDBの実行ステータスをリアルタイムで監視し、

See all articles