开发者

MongoDB索引类型汇总分享

目录
  • 单字段索引
    • 在单个字段上创建升序索引
    • 在嵌入式字段上创建索引
    • 在内嵌文档上创建索引
  • 复合索引
    • 多键索引
      • 文本索引
        • 2dsphere索引
          • 创建测试数据
          • 添加2dsphere索引
          • 利用2dsphere索引查询多边形里的点
          • 利用2dsphere索引查询球体上定义的圆内的点
        • 2d索引
          • 哈希索引

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

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

            单字段索引

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

            hand编程客栈ong1:PRIMARY> db.test.getIndexes()
            [
            	{
            		"v" : 2,
            		"key" : {
            			"_id" : 1
            		},
            		"name" : "_id_",
            		"ns" : "db6.test"
            	}
            ]
            

            在字段id上添加升序索引

            handong1:PRIMARY> db.test.createIndex({"id":1})
            {
            	"createdCollectionAutomatically" : false,
            	"numIndexesBefore" : 1,
            	"numIndexesAfter" : 2,
            	"ok" : 1,
            	"$clusterTime" : {
            		"clusterTime" : Timestamp(1621322378, 1),
            		"signature" : {
            			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            			"keyId" : NumberLong(0)
            		}
            	},
            	"operationTime" : Timestamp(1621322378, 1)
            }
            
            
            handong1:PRIMARY> db.test.getIndexes()
            [
            	{
            		"v" : 2,
            		"key" : {
            			"_id" : 1
            		},
            		"name" : "_id_",
            		"ns" : "db6.test"
            	},
            	{
            		"v" : 2,
            		"key" : {
            			"id" : 1
            		},
            		"name" : "id_1",
            		"ns" : "db6.test"
            	}
            ]
            
            
            handong1:PRIMARY> db.test.find({"id":100})
            { "_id" : ObjectId开发者_Kafka("60a35d061f183b1d8f092114"), "id" : 100, "name" : "handong", "ziliao" : { "name" : "handong", "age" : 25, "hobby" : "mongodb" laFlSjTBv} }
            
            

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

            在嵌入式字段上创建索引

            handong1:PRIMARY> db.test.createIndex({"ziliao.name":1})
            {
            	"createdCollectionAutomatically" : false,
            	"numIndexesBefore" : 2,
            	"numIndexesAfter" : 3,
            	"ok" : 1,
            	"$clusterTime" : {
            		"clusterTime" : Timestamp(1621323677, 2),
            		"signature" : {
            			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            			"keyId" : NumberLong(0)
            		}
            	},
            	"operationTime" : Timestamp(1621323677, 2)
            }
            
            

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

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

            在内嵌文档上创建索引

            handong1:PRIMARY> db.test.createIndex({ziliao:1})
            {
            	"createdCollectionAutomatically" : false,
            	"numIndexesBefore" : 3,
            	"numIndexesAfter" : 4,
            	"ok" : 1,
            	"$clusterTime" : {
            		"clusterTime" : Timestamp(1621324059, 2),
            		"signature" : {
            			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            			"keyId" : NumberLong(0)
            		}
            	},
            	"operationTime" : Timestamp(1621324059, 2)
            }
            
            

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

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

            复合索引

            创建复合索引

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

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

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

            多键索引

            基于一个数组创建索引,MongoDB会自动创建为多键索引,无需刻意指定。

            多键索引也可以基于内嵌文档来创建。

            多键索引的边界值的计算依赖于特定的规则。

            查看文档:

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

            创建score字段多键索引:

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

            查看执行计划:

            handong1:PRIMARY> db.score.find({"score":[ 96, 95 ]}).explain()
            {
            	"queryPlanner" : {
            		"plannerVersion" : 1,
            		"namespace" : "db6.score",
            		"indexFilterSet" : false,
            		"parsedQuery" : {
            			"score" : {
            				"$eq" : [
            					96,
            					95
            				]
            			}
            		},
            		"queryHash" : "8D76FC59",
            		"planCacheKey" : "E2B03CA1",
            		"winningPlan" : {
            			"stage" : "FETCH",
            			"filter" : {
            				"score" : {
            					"$eq" : [
            						96,
            						95
            					]
            				}
            			},
            			"inputStage" : {
            				"stage" : "IXSCAN",
            				"keyPattern" : {
            					"score" : 1
            				},
            				"indexName" : "score_1",
            				"isMultiKey" : true,
            				"multiKeyPaths" : {
            					"score" : [
            						"score"
            					]
            				},
            				"isUnique" : false,
            				"isSparse" : false,
            				"isPartial" : false,
            				"indexVersion" : 2,
            				"direction" : "forward",
            				"indexBounds" : {
            					"score" : [
            						"[96.0, 96.0]",
            						"[[ 96.0, 95.0 ], [ 96.0, 95.0 ]]"
            					]
            				}
            			}
            		},
            		"rejectedPlans" : [ ]
            	},
            	"serverInfo" : {
            		"host" : "mongo3",
            		"port" : 27017,
            		"version" : "4.2.12",
            		"gitVersion" : "5593fd8e33b60c75802edab304e23998fa0ce8a5"
            	},
            	"ok" : 1,
            	"$clusterTime" : {
            		"clusterTime" : Timestamp(1621326912, 1),
            		"signature" : {
            			"hash" : BinData(0,"AAAAhttp://www.devze.comAAAAAAAAAAAAAAAAAAAAAAA="),
            			"keyId" : NumberLong(0)
            		}
            	},
            	"operationTime" : Timestamp(1621326912, 1)
            }
            
            

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

            文本索引

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

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

            查看执行计划:

            handong1:PRIMARY> db.user.find({$text:{$search:"测试"}}).explain()
            {
            	"queryPlanner" : {
            		"plannerVersion" : 1,
            		"namespace" : "db6.user",
            		"indexFilterSet" : false,
            		"parsedQuery" : {
            			"$text" : {
            				"$search" : "测试",
            				"$language" : "english",
            				"$caseSensitive" : false,
            				"$diacriticSensitive" : false
            			}
            		},
            		"queryHash" : "83098EE1",
            		"planCacheKey" : "7E2D582B",
            		"winningPlan" : {
            			"stage" : "TEXT",
            			"indexPrefix" : {
            				
            			},
            			"indexName" : "sku_attributes_text",
            			"parsedTextQuery" : {
            				"terms" : [
            					"测试"
            				],
            				"negatedTerms" : [ ],
            				"phrases" : [ ],
            				"negatedPhrases" : [ ]
            			},
            			"textIndexVersion" : 3,
            			"inputStage" : {
            				"stage" : "TEXT_MATCH",
            				"inputStage" : {
            					"stage" : "FETCH",
            					"inputStage" : {
            						"stage" : "OR",
            						"inputStage" : {
            							"stage" : "IXSCAN",
            							"keyPattern" : {
            								"_fts" : "text",
            								"_ftsx" : 1
            							},
            							"indexName" : "sku_attributes_text",
            							"isMultiKey" : true,
            							"isUnique" : false,
            							"isSparse" : false,
            							"isPartial" : false,
            							"indexVersion" : 2,
            							"direction" : "backward",
            							"indexBounds" : {
            								
            							}
            						}
            					}
            				}
            			}
            		},
            		"rejectedPlans" : [ ]
            	},
            	"serverInfo" : {
            		"host" : "mongo3",
            		"port" : 27017,
            		"version" : "4.2.12",
            		"gitVersion" : "5593fd8e33b60c75802edab304e239laFlSjTBv98fa0ce8a5"
            	},
            	"ok" : 1,
            	"$clusterTime" : {
            		"clusterTime" : Timestamp(1621328543, 1),
            		"signature" : {
            			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            			"keyId" : NumberLong(0)
            		}
            	},
            	"operationTime" : Timestamp(1621328543, 1)
            }
            
            

            可以看到通过文本索引可以查到包含测试关键字的数据。

            **注意:**可以根据自己需要创建复合文本索引。

            2dsphere索引

            创建测试数据

            db.places.insert(
               {
                  loc : { type: "Point", coordinates: [ 116.291226, 39.981198 ] },
                  name: "火器营桥",
                  category : "火器营桥"
               }
            )
            
            
            db.places.insert(
               {
                  loc : { type: "Point", coordinates: [ 116.281452, 39.914226 ] },
                  name: "五棵松",
                  category : "五棵松"
               }
            )
            
            db.places.insert(
               {
                  loc : { type: "Point", coordinates: [ 116.378038, 39.851467 ] },
                  name: "角门西",
                  category : "角门西"
               }
            )
            
            
            db.places.insert(
               {
                  loc : { type: "Point", coordinates: [ 116.467833, 39.881581 ] },
                  name: "潘家园",
                  category : "潘家园"
               }
            )
            
            db.places.insert(
               {
                  loc : { type: "Point", coordinates: [ 116.468264, 39.914766 ] },
                  name: "国贸",
                  category : "国贸"
               }
            )
            
            db.places.insert(
               {
                  loc : { type: "Point", coordinates: [ 116.46618, 39.960213 ] },
                  name: "三元桥",
                  category : "三元桥"
               }
            )
            
            db.places.insert(
               {
                  loc : { type: "Point", coordinates: [ 116.400064, 40.007827 ] },
                  name: "奥林匹克森林公园",
                  category : "奥林匹克森林公园"
               }
            )
            

            添加2dsphere索引

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

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

            凤凰岭

            [116.098234,40.110569]

            天安门

            [116.405239,39.913839]

            四惠桥

            [116.494351,39.912068]

            望京

            [116.494494,40.004594]

            handong1:PRIMARY> db.places.find( { loc :
            ...                   { $geoWithin :
            ...                     { $geometry :
            ...                       { type : "Polygon" ,
            ...                         coordinates : [ [
            ...                                           [116.098234,40.110569] ,
            ...                                      编程客栈     [116.405239,39.913839] ,
            ...                                           [116.494351,39.912068] ,
            ...                                           [116.494494,40.004594] ,
            ...                                           [116.098234,40.110569]
            ...                                         ] ]
            ...                 } } } } )
            { "_id" : ObjectId("60a4c950d4211a77d22bf7f8"), "loc" : { "type" : "Point", "coordinates" : [ 116.400064, 40.007827 ] }, "name" : "奥林匹克森林公园", "category" : "奥林匹克森林公园" }
            { "_id" : ObjectId("60a4c94fd4211a77d22bf7f7"), "loc" : { "type" : "Point", "coordinates" : [ 116.46618, 39.960213 ] }, "name" : "三元桥", "category" : "三元桥" }
            { "_id" : ObjectId("60a4c94fd4211a77d22bf7f6"), "loc" : { "type" : "Point", "coordinates" : [ 116.468264, 39.914766 ] }, "name" : "国贸", "category" : "国贸" }
            
            

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

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

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

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

            2d索引

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

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

            哈希索引

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

            handong1:PRIMARY> db.test.createIndex({"_id":"hashed"})
            {
            	"createdCollectionAutomatically" : false,
            	"numIndexesBefore" : 4,
            	"numIndexesAfter" : 5,
            	"ok" : 1,
            	"$clusterTime" : {
            		"clusterTime" : Timestamp(1621419338, 1),
            		"signature" : {
            			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            			"keyId" : NumberLong(0)
            		}
            	},
            	"operationTime" : Timestamp(1621419338, 1)
            }
            
            

            注意事项

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

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

            0

            上一篇:

            下一篇:

            精彩评论

            暂无评论...
            验证码 换一张
            取 消

            最新数据库

            数据库排行榜