经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » MongoDB » 查看文章
MongoDB索引类型汇总分享
来源:jb51  时间:2022/4/11 8:45:02  对本文有异议

MongoDB 4.2官方支持索引类型如下:

  • 单字段索引
  • 复合索引
  • 多键索引
  • 文本索引
  • 2dsphere索引
  • 2d索引
  • geoHaystack索引
  • 哈希索引

单字段索引

在单个字段上创建升序索引

  1. handong1:PRIMARY> db.test.getIndexes()
  2. [
  3. {
  4. "v" : 2,
  5. "key" : {
  6. "_id" : 1
  7. },
  8. "name" : "_id_",
  9. "ns" : "db6.test"
  10. }
  11. ]

在字段id上添加升序索引

  1. handong1:PRIMARY> db.test.createIndex({"id":1})
  2. {
  3. "createdCollectionAutomatically" : false,
  4. "numIndexesBefore" : 1,
  5. "numIndexesAfter" : 2,
  6. "ok" : 1,
  7. "$clusterTime" : {
  8. "clusterTime" : Timestamp(1621322378, 1),
  9. "signature" : {
  10. "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
  11. "keyId" : NumberLong(0)
  12. }
  13. },
  14. "operationTime" : Timestamp(1621322378, 1)
  15. }
  16.  
  1. handong1:PRIMARY> db.test.getIndexes()
  2. [
  3. {
  4. "v" : 2,
  5. "key" : {
  6. "_id" : 1
  7. },
  8. "name" : "_id_",
  9. "ns" : "db6.test"
  10. },
  11. {
  12. "v" : 2,
  13. "key" : {
  14. "id" : 1
  15. },
  16. "name" : "id_1",
  17. "ns" : "db6.test"
  18. }
  19. ]
  20.  
  1. handong1:PRIMARY> db.test.find({"id":100})
  2. { "_id" : ObjectId("60a35d061f183b1d8f092114"), "id" : 100, "name" : "handong", "ziliao" : { "name" : "handong", "age" : 25, "hobby" : "mongodb" } }
  3.  

上述查询可以使用新建的单字段索引。

在嵌入式字段上创建索引

  1. handong1:PRIMARY> db.test.createIndex({"ziliao.name":1})
  2. {
  3. "createdCollectionAutomatically" : false,
  4. "numIndexesBefore" : 2,
  5. "numIndexesAfter" : 3,
  6. "ok" : 1,
  7. "$clusterTime" : {
  8. "clusterTime" : Timestamp(1621323677, 2),
  9. "signature" : {
  10. "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
  11. "keyId" : NumberLong(0)
  12. }
  13. },
  14. "operationTime" : Timestamp(1621323677, 2)
  15. }
  16.  

以下查询可以用的新建的索引。

  1. db.test.find({"ziliao.name":"handong"})

在内嵌文档上创建索引

  1. handong1:PRIMARY> db.test.createIndex({ziliao:1})
  2. {
  3. "createdCollectionAutomatically" : false,
  4. "numIndexesBefore" : 3,
  5. "numIndexesAfter" : 4,
  6. "ok" : 1,
  7. "$clusterTime" : {
  8. "clusterTime" : Timestamp(1621324059, 2),
  9. "signature" : {
  10. "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
  11. "keyId" : NumberLong(0)
  12. }
  13. },
  14. "operationTime" : Timestamp(1621324059, 2)
  15. }
  16.  

以下查询可以使用新建的索引。

  1. db.test.find({ziliao:{ "name" : "handong", "age" : 25, "hobby" : "mongodb" }})

复合索引

创建复合索引

  1. db.user.createIndex({"product_id":1,"type":-1})

以下查询可以用到新建的复合索引

  1. db.user.find({"product_id":"e5a35cfc70364d2092b8f5d14b1a3217","type":0})

多键索引

基于一个数组创建索引,MongoDB会自动创建为多键索引,无需刻意指定。
多键索引也可以基于内嵌文档来创建。
多键索引的边界值的计算依赖于特定的规则。
查看文档:

  1. handong1:PRIMARY> db.score.find()
  2. { "_id" : ObjectId("60a32d7f1f183b1d8f0920ad"), "name" : "dandan", "age" : 30, "score" : [ { "english" : 90, "math" : 99, "physics" : 88 } ], "is_del" : false }
  3. { "_id" : ObjectId("60a32d8b1f183b1d8f0920ae"), "name" : "dandan", "age" : 30, "score" : [ 99, 98, 97, 96 ], "is_del" : false }
  4. { "_id" : ObjectId("60a32d9a1f183b1d8f0920af"), "name" : "dandan", "age" : 30, "score" : [ 100, 100, 100, 100 ], "is_del" : false }
  5. { "_id" : ObjectId("60a32e8c1f183b1d8f0920b0"), "name" : "dandan", "age" : 30, "score" : [ { "english" : 70, "math" : 99, "physics" : 88 } ], "is_del" : false }
  6. { "_id" : ObjectId("60a37b141f183b1d8f0aa751"), "name" : "dandan", "age" : 30, "score" : [ 96, 95 ] }
  7. { "_id" : ObjectId("60a37b1d1f183b1d8f0aa752"), "name" : "dandan", "age" : 30, "score" : [ 96, 95, 94 ] }
  8. { "_id" : ObjectId("60a37b221f183b1d8f0aa753"), "name" : "dandan", "age" : 30, "score" : [ 96, 95, 94, 93 ] }
  9.  

创建score字段多键索引:

  1. db.score.createIndex("score":1)
  1. handong1:PRIMARY> db.score.find({"score":[ 96, 95 ]})
  2. { "_id" : ObjectId("60a37b141f183b1d8f0aa751"), "name" : "dandan", "age" : 30, "score" : [ 96, 95 ] }
  3.  

查看执行计划:

  1. handong1:PRIMARY> db.score.find({"score":[ 96, 95 ]}).explain()
  2. {
  3. "queryPlanner" : {
  4. "plannerVersion" : 1,
  5. "namespace" : "db6.score",
  6. "indexFilterSet" : false,
  7. "parsedQuery" : {
  8. "score" : {
  9. "$eq" : [
  10. 96,
  11. 95
  12. ]
  13. }
  14. },
  15. "queryHash" : "8D76FC59",
  16. "planCacheKey" : "E2B03CA1",
  17. "winningPlan" : {
  18. "stage" : "FETCH",
  19. "filter" : {
  20. "score" : {
  21. "$eq" : [
  22. 96,
  23. 95
  24. ]
  25. }
  26. },
  27. "inputStage" : {
  28. "stage" : "IXSCAN",
  29. "keyPattern" : {
  30. "score" : 1
  31. },
  32. "indexName" : "score_1",
  33. "isMultiKey" : true,
  34. "multiKeyPaths" : {
  35. "score" : [
  36. "score"
  37. ]
  38. },
  39. "isUnique" : false,
  40. "isSparse" : false,
  41. "isPartial" : false,
  42. "indexVersion" : 2,
  43. "direction" : "forward",
  44. "indexBounds" : {
  45. "score" : [
  46. "[96.0, 96.0]",
  47. "[[ 96.0, 95.0 ], [ 96.0, 95.0 ]]"
  48. ]
  49. }
  50. }
  51. },
  52. "rejectedPlans" : [ ]
  53. },
  54. "serverInfo" : {
  55. "host" : "mongo3",
  56. "port" : 27017,
  57. "version" : "4.2.12",
  58. "gitVersion" : "5593fd8e33b60c75802edab304e23998fa0ce8a5"
  59. },
  60. "ok" : 1,
  61. "$clusterTime" : {
  62. "clusterTime" : Timestamp(1621326912, 1),
  63. "signature" : {
  64. "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
  65. "keyId" : NumberLong(0)
  66. }
  67. },
  68. "operationTime" : Timestamp(1621326912, 1)
  69. }
  70.  

可以看到已经使用了新建的多键索引。

文本索引

    为了支持对字符串内容的文本搜索查询,MongoDB提供了文本索引。文本(text )索引可以包含任何值为字符串或字符串元素数组的字段

  1. db.user.createIndex({"sku_attributes":"text"})
  1. db.user.find({$text:{$search:"测试"}})

查看执行计划:

  1. handong1:PRIMARY> db.user.find({$text:{$search:"测试"}}).explain()
  2. {
  3. "queryPlanner" : {
  4. "plannerVersion" : 1,
  5. "namespace" : "db6.user",
  6. "indexFilterSet" : false,
  7. "parsedQuery" : {
  8. "$text" : {
  9. "$search" : "测试",
  10. "$language" : "english",
  11. "$caseSensitive" : false,
  12. "$diacriticSensitive" : false
  13. }
  14. },
  15. "queryHash" : "83098EE1",
  16. "planCacheKey" : "7E2D582B",
  17. "winningPlan" : {
  18. "stage" : "TEXT",
  19. "indexPrefix" : {
  20. },
  21. "indexName" : "sku_attributes_text",
  22. "parsedTextQuery" : {
  23. "terms" : [
  24. "测试"
  25. ],
  26. "negatedTerms" : [ ],
  27. "phrases" : [ ],
  28. "negatedPhrases" : [ ]
  29. },
  30. "textIndexVersion" : 3,
  31. "inputStage" : {
  32. "stage" : "TEXT_MATCH",
  33. "inputStage" : {
  34. "stage" : "FETCH",
  35. "inputStage" : {
  36. "stage" : "OR",
  37. "inputStage" : {
  38. "stage" : "IXSCAN",
  39. "keyPattern" : {
  40. "_fts" : "text",
  41. "_ftsx" : 1
  42. },
  43. "indexName" : "sku_attributes_text",
  44. "isMultiKey" : true,
  45. "isUnique" : false,
  46. "isSparse" : false,
  47. "isPartial" : false,
  48. "indexVersion" : 2,
  49. "direction" : "backward",
  50. "indexBounds" : {
  51. }
  52. }
  53. }
  54. }
  55. }
  56. },
  57. "rejectedPlans" : [ ]
  58. },
  59. "serverInfo" : {
  60. "host" : "mongo3",
  61. "port" : 27017,
  62. "version" : "4.2.12",
  63. "gitVersion" : "5593fd8e33b60c75802edab304e23998fa0ce8a5"
  64. },
  65. "ok" : 1,
  66. "$clusterTime" : {
  67. "clusterTime" : Timestamp(1621328543, 1),
  68. "signature" : {
  69. "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
  70. "keyId" : NumberLong(0)
  71. }
  72. },
  73. "operationTime" : Timestamp(1621328543, 1)
  74. }
  75.  

可以看到通过文本索引可以查到包含测试关键字的数据。
**注意:**可以根据自己需要创建复合文本索引。

2dsphere索引

创建测试数据

  1. db.places.insert(
  2. {
  3. loc : { type: "Point", coordinates: [ 116.291226, 39.981198 ] },
  4. name: "火器营桥",
  5. category : "火器营桥"
  6. }
  7. )
  8.  
  9.  
  10. db.places.insert(
  11. {
  12. loc : { type: "Point", coordinates: [ 116.281452, 39.914226 ] },
  13. name: "五棵松",
  14. category : "五棵松"
  15. }
  16. )
  17.  
  18. db.places.insert(
  19. {
  20. loc : { type: "Point", coordinates: [ 116.378038, 39.851467 ] },
  21. name: "角门西",
  22. category : "角门西"
  23. }
  24. )
  25.  
  26.  
  27. db.places.insert(
  28. {
  29. loc : { type: "Point", coordinates: [ 116.467833, 39.881581 ] },
  30. name: "潘家园",
  31. category : "潘家园"
  32. }
  33. )
  34.  
  35. db.places.insert(
  36. {
  37. loc : { type: "Point", coordinates: [ 116.468264, 39.914766 ] },
  38. name: "国贸",
  39. category : "国贸"
  40. }
  41. )
  42.  
  43. db.places.insert(
  44. {
  45. loc : { type: "Point", coordinates: [ 116.46618, 39.960213 ] },
  46. name: "三元桥",
  47. category : "三元桥"
  48. }
  49. )
  50.  
  51. db.places.insert(
  52. {
  53. loc : { type: "Point", coordinates: [ 116.400064, 40.007827 ] },
  54. name: "奥林匹克森林公园",
  55. category : "奥林匹克森林公园"
  56. }
  57. )

添加2dsphere索引

  1. db.places.createIndex( { loc : "2dsphere" } )
  2.  
  1. db.places.createIndex( { loc : "2dsphere" , category : -1, name: 1 } )
  2.  

利用2dsphere索引查询多边形里的点

凤凰岭
[116.098234,40.110569]
天安门
[116.405239,39.913839]
四惠桥
[116.494351,39.912068]
望京
[116.494494,40.004594]

  1. handong1:PRIMARY> db.places.find( { loc :
  2. ... { $geoWithin :
  3. ... { $geometry :
  4. ... { type : "Polygon" ,
  5. ... coordinates : [ [
  6. ... [116.098234,40.110569] ,
  7. ... [116.405239,39.913839] ,
  8. ... [116.494351,39.912068] ,
  9. ... [116.494494,40.004594] ,
  10. ... [116.098234,40.110569]
  11. ... ] ]
  12. ... } } } } )
  13. { "_id" : ObjectId("60a4c950d4211a77d22bf7f8"), "loc" : { "type" : "Point", "coordinates" : [ 116.400064, 40.007827 ] }, "name" : "奥林匹克森林公园", "category" : "奥林匹克森林公园" }
  14. { "_id" : ObjectId("60a4c94fd4211a77d22bf7f7"), "loc" : { "type" : "Point", "coordinates" : [ 116.46618, 39.960213 ] }, "name" : "三元桥", "category" : "三元桥" }
  15. { "_id" : ObjectId("60a4c94fd4211a77d22bf7f6"), "loc" : { "type" : "Point", "coordinates" : [ 116.468264, 39.914766 ] }, "name" : "国贸", "category" : "国贸" }
  16.  

可以看到把集合中包含在指定四边形里的点,全部列了出来。

利用2dsphere索引查询球体上定义的圆内的点

  1. handong1:PRIMARY> db.places.find( { loc :
  2. ... { $geoWithin :
  3. ... { $centerSphere :
  4. ... [ [ 116.439518, 39.954751 ] , 2/3963.2 ]
  5. ... } } } )
  6. { "_id" : ObjectId("60a4c94fd4211a77d22bf7f7"), "loc" : { "type" : "Point", "coordinates" : [ 116.46618, 39.960213 ] }, "name" : "三元桥", "category" : "三元桥" }
  7.  

返回所有半径为经度 116.439518 E 和纬度 39.954751 N 的2英里内坐标。示例将2英里的距离转换为弧度,通过除以地球近似的赤道半径3963.2英里。

2d索引

在以下情况下使用2d索引:

  • 您的数据库具有来自MongoDB 2.2或更早版本的旧版旧版坐标对。
  • 您不打算将任何位置数据存储为GeoJSON对象。

哈希索引

要创建hashed索引,请指定 hashed 作为索引键的值,如下例所示:

  1. handong1:PRIMARY> db.test.createIndex({"_id":"hashed"})
  2. {
  3. "createdCollectionAutomatically" : false,
  4. "numIndexesBefore" : 4,
  5. "numIndexesAfter" : 5,
  6. "ok" : 1,
  7. "$clusterTime" : {
  8. "clusterTime" : Timestamp(1621419338, 1),
  9. "signature" : {
  10. "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
  11. "keyId" : NumberLong(0)
  12. }
  13. },
  14. "operationTime" : Timestamp(1621419338, 1)
  15. }
  16.  

注意事项

  • MongoDB支持任何单个字段的 hashed 索引。hashing函数折叠嵌入的文档并计算整个值的hash值,但不支持多键(即.数组)索引。
  • 您不能创建具有hashed索引字段的复合索引,也不能在索引上指定唯一约束hashed;但是,您可以hashed在同一字段上创建索引和升序/降序(即非哈希)索引:MongoDB将对范围查询使用标量索引。

 到此这篇关于MongoDB索引类型汇总分享的文章就介绍到这了,更多相关MongoDB索引内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号