好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

MongoDB索引类型汇总分享

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

查看更多关于MongoDB索引类型汇总分享的详细内容...

  阅读:12次