検索
ホームページデータベースモンゴDBMongoDB の豊富なインデックス タイプについて話しましょう

この記事では、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

フィールド インデックスを構築しましょう。クエリが関連インデックスなしでフル テーブル スキャンを実行したことがわかります。<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>

ジョイント インデックス

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

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

sex は、2 つのフィールド

db.users.createIndex({age:1,sex:1})
&#39;age_1_sex_1&#39;
## を持つインデックスを作成します# 次に、これら 2 つのフィールドを使用してクエリを実行し、実行計画を確認し、このインデックスを正常に実行します <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>

配列インデックス

配列インデックスは、配列フィールドのインデックス (複数値インデックスとも呼ばれます)。テストするために、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 番目の次元空間インデックスの作成 <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>地理空間インデックスの

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 までご連絡ください。
MongoDB対リレーショナルデータベース:比較MongoDB対リレーショナルデータベース:比較Apr 18, 2025 am 12:08 AM

MongoDBは、柔軟なデータモデルと高いスケーラビリティを必要とするシナリオに適していますが、リレーショナルデータベースは、複雑なクエリとトランザクション処理を使用するアプリケーションにより適しています。 1)Mongodbのドキュメントモデルは、迅速な反復現代アプリケーション開発に適応します。 2)リレーショナルデータベースは、テーブル構造とSQLを通じて複雑なクエリと金融システムをサポートします。 3)MongoDBは、大規模なデータ処理に適したシャードを介して水平スケーリングを実現します。 4)リレーショナルデータベースは垂直拡張に依存しており、クエリとインデックスを最適化する必要があるシナリオに適しています。

Mongodb vs. Oracle:パフォーマンスとスケーラビリティを調べますMongodb vs. Oracle:パフォーマンスとスケーラビリティを調べますApr 17, 2025 am 12:04 AM

MongoDBは、高いスケーラビリティと柔軟性の要件に適したパフォーマンスとスケーラビリティが優れています。 Oracleは、厳格なトランザクション制御と複雑なクエリを要求する上で優れたパフォーマンスを発揮します。 1.MongoDBは、大規模なデータと高い並行性シナリオに適した、シャードテクノロジーを通じて高いスケーラビリティを実現します。 2。Oracleは、構造化されたデータとトランザクション制御のニーズに適したパフォーマンスを改善するために、オプティマイザーと並列処理に依存しています。

Mongodb vs. Oracle:重要な違​​いの理解Mongodb vs. Oracle:重要な違​​いの理解Apr 16, 2025 am 12:01 AM

MongoDBは、大規模な構造化されていないデータの処理に適しており、Oracleはトランザクションの一貫性を必要とするエンタープライズレベルのアプリケーションに適しています。 1.MongoDBは、ユーザーの動作データの処理に適した柔軟性と高性能を提供します。 2。Oracleは、その安定性と強力な機能で知られており、金融システムに適しています。 3.MongoDBはドキュメントモデルを使用し、Oracleはリレーショナルモデルを使用します。 4.MongoDBはソーシャルメディアアプリケーションに適していますが、Oracleはエンタープライズレベルのアプリケーションに適しています。

MongoDB:スケーリングとパフォーマンスの考慮事項MongoDB:スケーリングとパフォーマンスの考慮事項Apr 15, 2025 am 12:02 AM

MongoDBのスケーラビリティとパフォーマンスの考慮事項には、水平スケーリング、垂直スケーリング、パフォーマンスの最適化が含まれます。 1.システム容量を改善するために、シャードテクノロジーを通じて水平拡張が達成されます。 2。垂直拡張により、ハードウェアリソースを増やすことでパフォーマンスが向上します。 3.パフォーマンスの最適化は、インデックスの合理的な設計と最適化されたクエリ戦略を通じて達成されます。

Mongodbの力:現代のデータ管理Mongodbの力:現代のデータ管理Apr 13, 2025 am 12:04 AM

MongoDBは、柔軟性とスケーラビリティが最新のデータ管理において非常に重要であるため、NOSQLデータベースです。ドキュメントストレージを使用し、大規模で可変デー​​タの処理に適しており、強力なクエリとインデックスの機能を提供します。

バッチでmongodbを削除する方法バッチでmongodbを削除する方法Apr 12, 2025 am 09:27 AM

次の方法を使用して、MongoDBでドキュメントを削除できます。1。オペレーターの$は、削除するドキュメントのリストを指定します。 2。正規表現は、基準を満たすドキュメントと一致します。 3. $ exists演算子は、指定されたフィールドを使用してドキュメントを削除します。 4。sing()およびremove()メソッドは、最初にドキュメントを取得して削除します。これらの操作はトランザクションを使用できず、一致するすべてのドキュメントを削除する場合があるため、使用する場合は注意してください。

MongoDBコマンドを設定する方法MongoDBコマンドを設定する方法Apr 12, 2025 am 09:24 AM

MongoDBデータベースをセットアップするには、コマンドライン(使用およびdb.createcollection())またはMongoシェル(Mongo、Use、DB.CreateCollection())を使用できます。その他の設定オプションには、データベースの表示(DBSの表示)、コレクションの表示(コレクションの表示)、データベースの削除(db.dropdatabase())、db。&amp; collection_name&amp; gt; drop())、挿入文書(db; lt; lt; lt; collection

MongoDBクラスターの展開方法MongoDBクラスターの展開方法Apr 12, 2025 am 09:21 AM

MongoDBクラスターの展開は、プライマリノードの展開、セカンダリノードの展開、セカンダリノードの追加、複製の構成、クラスターの検証の5つのステップに分割されます。 MongoDBソフトウェアのインストール、データディレクトリの作成、MongoDBインスタンスの開始、レプリケーションセットの初期化、セカンダリノードの追加、レプリカセットの機能の有効化、投票権の構成、クラスターステータスとデータレプリケーションの検証などが含まれます。

See all articles

ホット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ヘンタイを無料で生成します。

ホットツール

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター

メモ帳++7.3.1

メモ帳++7.3.1

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

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

WebStorm Mac版

WebStorm Mac版

便利なJavaScript開発ツール

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン