• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

MongoDB :滴滴、摩拜都在用的索引-educoder上面的题目以和笔记

武飞扬头像
00的小尾巴
帮助2

MongoDB 之滴滴、摩拜都在用的索引

(MapReduce的在后面)

第一关:了解并创建一个简单索引

索引的原理:

对某个键按照升续或降续创建索引,查询时首先根据查询条件查找到对应的索引条目,然后找到索引条目对应的文档指针(文档在磁盘上的存储位置),根据文档指针再去磁盘中找到相应的文档,整个过程不需要扫描全表,速度比较快

每个文档被插入集合时,如果没有给它指定索引_id,MongoDB 会自动给它创建一个默认索引_id,是个 ObjectId 对象

学新通

索引基本操作

1、创建索引(单字段索引)

db.person.createIndex({key:1})
  1. key :要创建索引的键;
  2. 如果为 1, 按照升序创建索引,而如果为 -1,则是按降序创建索引

学新通

2、查询索引

(1).查询集合索引:

db.person.getIndexes()

学新通

(2)查询全部索引

db.system.indexes.find()

学新通

3、删除索引

(1)通过指定索引名称删除该索引:

db.person.dropIndex("ageIdx")

(2).通过指定集合删除集合中的全部索引:

db.person.dropIndexes()

学新通

编程测试代码:

  1.  
    document=([
  2.  
     
  3.  
    {_id:1,name: "王小明",age:15,score:90},
  4.  
     
  5.  
    {_id:2,name: "周晓晓",age:18,score:86},
  6.  
     
  7.  
    {_id:3,name: "王敏",age:20,score:96},
  8.  
     
  9.  
    {_id:4,name: "李小亮",age:15,score:74},
  10.  
     
  11.  
    {_id:5,name: "张青青",age:21,score:88}
  12.  
     
  13.  
    ])
  14.  
     
  15.  
    db.student.insert(document)
  16.  
     
  17.  
    db.student.createIndex({score:-1})
学新通

第二关:常见索引的创建

创建常见索引:

创建索引的基本语法: db.集合.createIndex({属性1: 1/-1, 属性2: 1/-1})

1、创建复合索引

和创建单字段索引的方法差不多,只是选取了多个键一同作为索引,中间以逗号隔开:

db.person.createIndex({age: 1, name: 1})

学新通

2、创建多 key 索引

当索引的字段为数组时,创建出的索引称为多 key 索引,多 key 索引会为数组的每个元素建立一条索引,比如 person 集合加入一个 habbit 字段(数组)用于描述兴趣爱好:

{name : '王小明', age : 19, habbit: ['football', 'runnning']}

需要查询有相同兴趣爱好的人就可以利用 habbit 字段的多 key 索引。

  1.  
    db.person.createIndex( {habbit: 1} )     // 升序创建多key索引
  2.  
     
  3.  
    db.person.find({habbit: 'football'})     //查找喜欢足球的人

学新通

3、创建哈希索引

创建命令如下:

学新通

4、文本索引的创建与使用

假如我们用 Mongodb 存储了很多博客文章,那么如何快速找到所有关于 mongodb 这个主题的文章呢?这时候就要用到文本搜索了。

(1). 创建文本索引命令:

创建单个字段的文本索引

db.collection.createIndex({ title: 'text'})
  1. 创建全文本索引的字段必须为 string 格式;
  2. 每个集合只支持一个文本索引

学新通

创建多个字段的文本索引

  1.  
    db.collection.createIndex(
  2.  
     
  3.  
      {
  4.  
     
  5.  
         title: 'text',
  6.  
     
  7.  
         tags: 'text'
  8.  
     
  9.  
      }
  10.  
     
  11.  
    )

学新通

(2). 使用文本索引;

现在我们已经创建了 title 的索引,我们来搜索一下含有 educoder.net 的文章:

  1. search 后的关键词可以有多个,关键词之间的分隔符可以是多种字符,例如空格、下划线、逗号、加号等,但不能是-和\,因为这两个符号会有其他用途。搜索的多个关键字是 or 的关系,除非你的关键字包含-;
  2. 匹配时不是完整的单词匹配,相似的词也可以匹配到;
db.collection.find({$text:{$search:'educoder.net'}})

学新通

(3). 删除文本索引

1.  通过命令获取索引名:

db.collection.getIndexes()
  1. 删除命令:
db.collection.dropIndex('title_text')

学新通

编程测试代码(部分):😊

  1.  
    db.article.insert([
  2.  
     
  3.  
    {_id:1,title: "提升程序员工作效率的6个工具利器",tags:[ "Alfred ", "幕布"],follwers:543},
  4.  
     
  5.  
    {_id:1,title:"我是如何从零开始学习前端的",tags:["HTML","Html5","CSS "],follwers:1570},
  6.  
     
  7.  
    {_id:1,title: "20个非常有用的JAVA程序片段",tags:[ "Java ", "编程"],follwers:1920}])
  1.  
    db.article.createIndex({follwers:1,title:1})
  2.  
     
  3.  
    db.article.createIndex({tags:-1})
  4.  
     
  5.  
    db.article.createIndex({_id:"hashed"})
  6.  
     
  7.  
    db.article.createIndex( { title:'text',tags:'text'})
  8.  
     
  9.  
    db.article.getIndexes()

第三关:有趣的地理位置

相关知识:

1、GeoJson 数据

只有拥有特定格式的文档才可以创建。

如果我们用的是 2dsphere 索引,那么插入的应该是 GeoJson 数据。GeoJson 的格式如是:

     { type: ‘GeoJSON type’ , coordinates: ‘coordinates’ }

  1. type :指的是类型,可以是 Point (本例中用的,点)、LineString(线)、 Polygon(面) 等;
  2. coordinates :指的是一个坐标数组
  1.  
    db.locations.insert({_id:1,name:'长沙站',location:{type:'Point',coordinates:[113.018987,28.201215]}})
  2.  
     
  3.  
    db.locations.insert({_id:2,name:'湖南师范大学',location:{type:'Point',coordinates:[112.946045,28.170968]}})
  4.  
     
  5.  
    db.locations.insert({_id:3,name:'中南大学',location:{type:'Point',coordinates:[112.932175,28.178291]}})
  6.  
     
  7.  
    db.locations.insert({_id:4,name:'湖南女子学院',location:{type:'Point',coordinates:[113.014675,28.121163]}})
  8.  
     
  9.  
    db.locations.insert({_id:5,name:"湖南农业大学",location:{type:'Point',coordinates:[113.090852,28.187461]}})

2、创建地理位置索引

一般的代码:  db.集合.createIndex({创建索引的属性:  ’ 2dsphere’ })

  1. 2d :平面坐标索引,适用于基于平面的坐标计算,也支持球面距离计算,不过官方推荐使用 2dsphere 索引;
  2. 2dsphere :几何球体索引,适用于球面几何运算(一般都是用这个!!!)
  3. 默认情况下,地理位置索引会假设值的范围是从−180到180(根据经纬度设置)。

db.locations.createIndex({location:'2dsphere'})学新通

3、地理位置索引的使用

查询命令:(很重要!!!)

  1.  
    db.runCommand({
  2.  
     
  3.  
        geoNear:'locations',
  4.  
     
  5.  
        near:{type:'Point',coordinates:[113.018987,28.201215]},   (一般是location)
  6.  
     
  7.  
        spherical:true
  8.  
     
  9.  
        minDistance:1000,
  10.  
     
  11.  
        maxDistance:8000
  12.  
     
  13.  
        })
  1. geoNear :我们要查询的集合名称
  2. near :就是基于那个点进行搜索,这里是我们的搜索点“长沙站”;
  3. spherical :是个布尔值,如果为 true,表示将计算实际的物理距离,比如两点之间有多少 km,若为 false,则会基于点的单位进行计算 ;
  4. minDistance :搜索的最小距离,这里的单位是米
  5. maxDistance :搜索的最大距离。

学新通

编程测试代码:

  1.  
    db.people.insert({_id:1,name:'A',personloc:{type:'Point',coordinates:[116.403981,39.914935]}});
  2.  
     
  3.  
    db.people.insert({_id:2,name:'B',personloc:{type:'Point',coordinates:[116.433733,39.909511]}});
  4.  
     
  5.  
    db.people.insert({_id:3,name:'C',personloc:{type:'Point',coordinates:[116.488781,39.949901]}});
  6.  
     
  7.  
    db.people.insert({_id:4,name:'D',personloc:{type:'Point',coordinates:[116.342609,39.948021]}});
  8.  
     
  9.  
    db.people.insert({_id:5,name:'E',personloc:{type:'Point',coordinates:[116.328236,39.901098]}});
  10.  
     
  11.  
    db.people.insert({_id:6,name:'F',personloc:{type:'Point',coordinates:[116.385728,39.871645]}});
  12.  
     
  13.  
    db.people.createIndex({personloc:'2dsphere'});
  14.  
     
  15.  
    db.runCommand({
  16.  
     
  17.  
        geoNear:'people',
  18.  
     
  19.  
        near:{type:'Point',coordinates:[116.403981,39.914935]},
  20.  
     
  21.  
        spherical:true,
  22.  
     
  23.  
        minDistance:100,
  24.  
     
  25.  
        maxDistance:3000
  26.  
     
  27.  
    });
  28.  
     
  29.  
    db.runCommand({
  30.  
     
  31.  
        geoNear:'people',
  32.  
     
  33.  
        near:{type:'Point',coordinates:[116.433733,39.909511]},
  34.  
     
  35.  
        spherical:true,
  36.  
     
  37.  
        minDistance:100,
  38.  
     
  39.  
        maxDistance:5000
  40.  
     
  41.  
    });
  42.  
     
  43.  
    db.runCommand({
  44.  
     
  45.  
        geoNear:'people',
  46.  
     
  47.  
        near:{type:'Point',coordinates:[116.488781,39.949901]},
  48.  
     
  49.  
        spherical:true,
  50.  
     
  51.  
        minDistance:3000,
  52.  
     
  53.  
        maxDistance:8000
  54.  
     
  55.  
    });
  56.  
     
  57.  
    db.runCommand({
  58.  
     
  59.  
        geoNear:'people',
  60.  
     
  61.  
        near:{type:'Point',coordinates:[116.342609,39.948021]},
  62.  
     
  63.  
        spherical:true,
  64.  
     
  65.  
        minDistance:3000,
  66.  
     
  67.  
        maxDistance:8000});
学新通

MapReduce查询:

操作语法:

  1.  
    db.集合名称.mapReduce(
  2.  
     
  3.  
    function(){emit(key, values)},   map:key是需要聚合的属性,values是操作值的属性
  4.  
     
  5.  
    function(key, values){return Array.操作(values)},  reduce:操作:sum,avg,min,max,first
  6.  
     
  7.  
    {query: 条件,
  8.  
     
  9.  
    out: 存储到新的集合的名称,
  10.  
     
  11.  
    sort: 条件,
  12.  
     
  13.  
    limit: number
  14.  
     
  15.  
    }
  16.  
     
  17.  
    )
学新通

进行查询操作练习:

  1.  
    db.educoder.mapReduce(
  2.  
     
  3.  
                         function(){emit(this.author,this.learning_num);},
  4.  
     
  5.  
                         function(key,values){return Array.avg(values)},
  6.  
     
  7.  
                         {
  8.  
     
  9.  
                         out:"avg_num"
  10.  
     
  11.  
                         }
  12.  
     
  13.  
    )

db.avg_num.find()学新通

  1.  
    db.educoder.mapReduce(
  2.  
     
  3.  
                         function(){emit(this.author,this.learning_num);},
  4.  
     
  5.  
                         function(key,values){return Array.avg(values)},
  6.  
     
  7.  
                         {
  8.  
     
  9.  
                         out:"avg_num",
  10.  
     
  11.  
                         limit:2
  12.  
     
  13.  
                         }
  14.  
     
  15.  
    )
学新通

db.avg_num.find()

学新通

  1.  
    db.educoder.mapReduce(
  2.  
                   function(){
  3.  
    emit(this.author,this.learning_num);
  4.  
    },
  5.  
                   function(key,values){
  6.  
    return Array.avg(values)
  7.  
    },
  8.  
     
  9.  
                         {
  10.  
                         query: {author: "李暾"},
  11.  
                         out:"avg_num",
  12.  
                         }
  13.  
    )
  14.  
     
  15.  
    db.avg_num.find()
学新通

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgacbee
系列文章
更多 icon
同类精品
更多 icon
继续加载