【mongo系列】二、mongo基本概念及操作

一、mongodb的架构

【mongo系列】二、mongo基本概念及操作

1. database:

​ 一个mongo实例包含多个数据库(database)。类似mysql中的数据库

2. collection:

​ 一个数据库中包含多个集合(collection)。类似mysql中的表

3. document:

​ 一个集合中包含多个文档(document)。类似mysql中的一行记录,但是一个json类型的文档,并且document的格式不固定,同一个collection中的document不要求有同样的格式(但为了便于使用和管理,建议都是同样格式)

​ 在同一个collection中的每个document都会包含一个唯一的_id字段,可以手动指定(比如自增键),或者插入数据时不指定,会自动生成_id

​ 单条document不能大于16M

​ document嵌套深度不能超过100

二、database基本操作

  • 1.查看所有数据库

    show dbs
  • 2.切换数据库

    use db_name
  • 3.获取当前所在的数据库名称

    db.getName()
  • 4.查看当前库下的所有collection名称

    db.getCollectionNames()
  • 5.删除当前库

    db.dropDatabase()

三、collection基本操作

1. 插入

collection中插入document,不需要提前创建collection。若collection不存在,会自动创建

(也可以通过db.createCollection('testcol')显式创建)

插入有三种方法:insert(document,options),insertOne(document,options),insertMany([documents],options)

  • insertOne()

    一次插入一条数据,插入的值是json串,插入成功返回document的id

    db.testcol.insertOne({"a":1,"b":2})
  • insertMany()

    一次插入多条数据,插入的值是一个数组,插入成功返回包含所有document的id的数组

    db.testcol.insertMany([{"a":1,"b":2},{"a":2,"b":3}])
  • insert()

    insert可以一次插入一条,或多条,返回插入成功的记录数

    db.testcol.insert({"a":1,"b":2})
    db.testcol.insert([{"a":1,"b":2},{"a":2,"b":3}])
  • 其他说明
  1. 不建议使用insert()方法

    insert()方法可以同时插入单条或多条,但insert()方法不会返回插入文档的id,而我们经常需要记录此生成的id,因此建议使用insertOne()insertMany()

  2. collection中的格式不要求相同(为了便于使用和管理最好还是相同或相似)

  3. 每条记录都会包含_id字段,该字段不可重复,如果不指定,则会自动生成

  4. insertMany()插入顺序的影响

    默认情况下insertMany()是按照顺序插入的,当其中某条记录插入异常时,会报错终止,那么此记录之前的数据可以正常插入,之后的数据没有插入

    // 插入一条记录制指定id为2
    db.testcol.insertOne({"_id":2,"value":1})
    // 再插入三条记录,则id为1的记录可以成功,后两条都不会插入
    db.testcol.insertMany([{"_id":1,"value":1},{"_id":2,"value":1},{"_id":3,"value":1}])

    解决这个问题,可以指定不按顺序,则会尝试插入每一个值

    // 不按顺序,失败的数据会跳过
    db.testcol.insertMany([{"_id":1,"value":1},{"_id":2,"value":1},{"_id":3,"value":1}],{ordered:false})

2. 查找

查找的两种方法find(filter,options)和findOne(filter,options)方法

filter指定查询条件可以不写,也可以为空({})

options调整输出形式

  • 查找全部文档find()

    find()默认返回前20条数据,可以输入it命令翻页

    db.testcol.find()
    // 或者也可以传入一个空的过滤条件
    db.testcol.find({})

    pretty()方法会把输出结果进行格式化,方便查看

    db.testcol.find().pretty()
  • 查找单条文档findOne()

    findOne()返回结果已经做了格式化,不能再加pretty()

    db.testcol.findOne()
  • 结果转换数组

    db.testcol.find().toArray()
  • 简单条件过滤

    // 仅查询字段a为1的记录
    db.testcol.find({a:1})
  • 返回指定字段

    通过options控制返回行为

    // 只返回字段a(_id字段都会返回),没有字段a的记录只返回_id
    db.testcol.find({},{"a":1})

3. 深入查找

  • 嵌套查找

    比如插入如下格式文档,文档中contact字段是嵌套的字典,hobby_list字段是嵌套的列表

    {
      "name" : "Tom",
      "age" : 27,
      "contact":{
            "phone":"123456",
            "mail":"[email protected]"
      },
      "hobby_list": ["Movie","Sports"],
      "hobby" : [
        {
              "type" : "Movie",
            "rating" : 3
          },
          {
              "type" : "Sports",
              "rating" : 6
        }
      ]
    },
    {
      "name" : "Jack",
      "age" : 25,
      "contact":{
          "phone":"456123",
          "mail":"[email protected]"
      },
      "hobby_list": ["Movie","Cook","Music"],
      "hobby" : [
          {
              "type" : "Movie",
              "rating" : 2
          },
          {
              "type" : "Cook",
              "rating" : 5
          },
          {
              "type" : "Music",
              "rating" : 4
          }
      ]
    }

    字典嵌套

    // 使用`.`查询contact中的phone等于456123的记录,嵌套查询的key双引号不能省略
    db.testcol.find({"contact.phon":"456123"})

    数组嵌套:

    // 查询字段hobby_list中包含Movie的记录,这会返回两条记录
    db.testcol.find({hobby_list:"Movie"})
    // 完全匹配hobby_list字段
    db.testcol.find({hobby_list:["Movie","Sports"]})
  • 包含、不包含($in,$nin)

    // 查找hobby_list中包含Movie或者包含"Sports"的记录
    db.testcol.find({hobby_list:{$in:["Movie","Sports"]}})
    // 查找hobby_list中不包含Movie并且也不包含Sports的记录
    db.testcol.find({hobby_list:{$nin:["Movie","Sports"]}})
  • 比较操作符

    $ep :等于
    $ne :不等于
    $gt :大于
    $gte :大于等于
    $lt :小于
    $lte :小于等于
    // 查找字段age大于26的记录
    db.testcol.find({age:{$gt:26}})
  • 逻辑操作符

    $and
    $not
    $or
    $nor
    // 查找age大于30或者age小于20的记录
    db.testcol.find({$or:[{age:{$gt:30}},{age:{$lt:20}}]})
  • 元素操作符

    $exists : 元素是否存在
    $type  :字段类型
    // 查找存在age字段的记录
    db.testcol.find({age:{$exists:true}})
    // 查找age字段是字符串的记录
    db.testcol.find({age:{$type:"string"}})
  • 数组相关查询

    $size : 数组长度
    $elemMatch : 数组内对象匹配
    // 查询hobby数量是3的记录
    db.testcol.find({hobby:{$size:3}})
    // 查询hobby中有Movie并且Movie的rating是2 的记录
    db.testcol.find({hobby:{$elemMatch:{type:"Movie",rating:2}}})
  • 排序

    1正序,-1倒叙

    单字段排序

    // 按age字段正序排序
    db.testcol.find().sort({age:1})

    多字段排序

    // 先按age正序排序,再按name倒叙排序
    db.testcol.find().sort({age:1,name:-1})
  • limit和skip

    limit限制返回的记录数

    // 只看前三条数据
    db.testcol.find().limit(3)

    skip跳过数据

    // 跳过前3条,查看第4-6条
    db.testcol.find().limit(3).skip(3)

    注:limit结合sort使用时,是先排序再limit,并不是对结果集的排序,要对结果排序使用聚合方法

    // 先按照age升序排序后,再取前三条数据。并不是先取三条在排序
    db.testcol.find().limit(3).sort({age:1})

4. 删除

deleteOne(filter,options)删除一条

delteMany(filter,options)删除多条

  • deleteOne()

    deleteOne删除一条,若有多条匹配条件则删除第一条

    // 删除age等于27的第一条记录
    db.testcol.deleteOne({age:27})
  • delteMany()

    删除所有符合条件的数据

    // 删除age大于27的所有数据
    db.testcol.deleteMany({age:{$gt:27}})
    // 删除所有数据
    db.testcol.deleteMany({})
  • 删除collection

    db.testcol.drop()

5. 更新的简单用法

updateOne(filter,options) : 更新匹配到的第一条

updateMany(filter,options) : 更新匹配到的所有值

update(filter,options) :可以使用json对象直接覆盖整个对象,而不是修改单一字段

replaceOne(filter,options) :替换对象

  • updateOne()

    // 把满足字段a等于1的第一条记录的字段b的值改为2
    db.testcol.updateOne({a:1},{$set:{b:2}})
  • updateMany()

    // 把满足字段a等于1的所有记录的字段b的值改为2
    db.testcol.updateMany({a:1},{$set:{b:2}})
  • update()

    当使用$set变量时,和updateOne类似

    // 把满足字段a等于1的第一条记录的字段b的值改为2
    db.testcol.update({a:1},{$set:{b:2}})

    当使用json字符串时,不是对单个字段的修改,而是覆盖整个对象

    // 把满足字段a等于1的第一条记录更新为{a:1,b:3}(并不是更新a和b字段,是覆盖了整个对象)
    db.testcol.update({a:1},{a:1,b:3})
  • replaceOne()

    和update语句使用json替换整个对象类似

    // 把满足字段a等于1的第一条记录更新为{a:3,b:4}(并不是更新a和b字段,是覆盖了整个对象)
    db.testcol.replaceOne({a:1},{a:3,b:4})

6. 更新的其他用法

  • unset

    删除字段

    // 删除testcol的a字段
    db.testcol.updateMany({},{$unset:{a:1}})
  • rename

    修改字段的名称

    // 把字段a重命名为a1
    db.testcol.updateMany({},{$rename:{a:"a1"}})
  • lnc

    增加或减少

    // a等于1的记录的b字段增加1
    db.testcol.updateMany({a:1},{$inc:{b:1}})
    // 减少1
    db.testcol.updateMany({a:1},{$inc:{b:-1}})
  • max

    更新为两者的最大值

    // 若b>10则不更新,否则更新b为10
    db.testcol.updateMany({a:1},{$max:{b:10}})
  • min

    更新为两者的最小值

    // 若b<10则不更新,否则更新b为10
    db.testcol.updateMany({a:1},{$min:{b:10}})
  • 嵌套对象的更新

    我们还用深入查找章节的的json例子,我们想要把hobby中满足type是movie并且rating是3的记录的rating增加1

    // 使用$符合,表示前面elemMatch匹配到的对象
    db.testcol.updateMany(
    {hobby:
      {$elemMatch:
          {$and:[
              {type:"Movie"},
              {rating:3}
          ]}
      }
    },
    {$inc:
      {"hobby.$.rating":1}
    }
    )
  • upsert

    update操作加上upsert选项,当匹配到值时执行更新操作,当没有匹配到值时则插入这条数据

    插入的数据包含匹配字段,如下:若没有匹配到数据则插入{a:1,b:1,c:1}记录

    // 有匹配则更新,无匹配则插入
    db.testcol.updateOne({a:1},{$set:{b:1,c:1}},{upsert:true})

欢迎关注公众号,不定时更新运维技术文章
【mongo系列】二、mongo基本概念及操作

猜你喜欢

转载自blog.51cto.com/epime/2490028
今日推荐