服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|数据库技术|

服务器之家 - 数据库 - MongoDB - MongoDB索引类型汇总分享

MongoDB索引类型汇总分享

2022-10-08 16:59那海蓝蓝 MongoDB

这篇文章主要介绍了MongoDB索引类型汇总,单字段索引、复合索引、多键索引、文本索引、2dsphere索引等多种索引类型,需要的朋友可以参考一下

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

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

单字段索引

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

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

在字段id上添加升序索引

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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)
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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"
    }
]
?
1
2
handong1:PRIMARY> db.test.find({"id":100})
{ "_id" : ObjectId("60a35d061f183b1d8f092114"), "id" : 100, "name" : "handong", "ziliao" : { "name" : "handong", "age" : 25, "hobby" : "mongodb" } }

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

在嵌入式字段上创建索引

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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)
}

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

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

在内嵌文档上创建索引

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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)
}

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

?
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
2
3
4
5
6
7
8
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字段多键索引:

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

查看执行计划:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    },
    "operationTime" : Timestamp(1621326912, 1)
}

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

文本索引

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

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

查看执行计划:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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" : "5593fd8e33b60c75802edab304e23998fa0ce8a5"
    },
    "ok" : 1,
    "$clusterTime" : {
        "clusterTime" : Timestamp(1621328543, 1),
        "signature" : {
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    },
    "operationTime" : Timestamp(1621328543, 1)
}

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

2dsphere索引

创建测试数据

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
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索引

?
1
db.places.createIndex( { loc : "2dsphere" } )
?
1
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]

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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索引查询球体上定义的圆内的点

?
1
2
3
4
5
6
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 作为索引键的值,如下例所示:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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索引内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.51cto.com/u_12592884/2786578

延伸 · 阅读

精彩推荐