MongoDB

关于database的基础命令

• 查看当前的数据库:db
• 查看所有的数据库:show dbs / show databases
• 切换数据库:use db_name
• 删除当前数据库:db.dropDatabase()

mongodb不需要创建数据库,无论有没有数据库,当我们使用use命令时都可以直接切换,存入数据时,才会自动创建。

关于集合(类表)的基础命令

不手动创建集合
向不存在的集合中第一次加入数据时,集合被创建出来。

手动创建集合

  db.createCollection(name,options)
  db.createCollection("stu")
  db.createCollection("sub",{capped:true,size:10})

参数capped:默认值为false表示不设置上限,值为true表示设置上限
参数size:当capped值为true时,需要指定此参数,表示上限大小,当文档达到上限时,会将之前的数据覆盖,单位为字节。

查看集合

show collections

删除集合

db.collection_name.drop()

数据类型

  • Object ID:文档ID
  • String:字符串,最常用的,必须是有效的UTF-8
  • Boolean:存储一个布尔值,true或false
  • Integer:整数可以是32位或64位,这取决于服务器
  • Double:存储浮点值
  • Arrays:数组或列表,多个值存储到一个键
  • Object:用于嵌入式的文档,即一个值为一个文档(就是一个字典)
  • Null:存储Null值
  • Timestamp:时间戳,表示从1970-1-1到现在的总秒数
  • Date:存储当前日期或时间的UNIX时间格式

注意:

  • 创建日期语句如下:参数的格式为YYYY-MM-DD
    new Date('2017-12-20')
  • 每个文档都有一个属性,为_id, 保证每个文档的唯一性
  • 可以自己去设置_id插入文档,如果没有提供,那么MonogoDB为每一个文档提供了独特的_id,类型为objectID
  • objectID是一个12字节的十六进制数:
    • 前4个字节为当前时间戳
    • 接下来3个字节为机器ID
    • 接下来的2个字节中MongoDB的服务进程ID
    • 最后3个字节是简单的增量值

插入

 db.db_name.insert(document)
 db.db_name.insert({name:"bruce",age:18})
 db.db_name.insert({_id:"20181204",name:"bruce",gender:1})
  • 插入文档时,如果不指定_id参数,MongoDB会为文档分配一个唯一的ObjectID
  • 如果执行insert操作,_id重复的话,会抛出错误。

保存

 db.collection_name.save(document)
  • 如果文旦的_id已经存在则修改,如果文档的_id不存在则添加
  • save执行时,_id重复的话,会执行更新操作。

简单查询

db.db_name.find()
db.collection_name.find()

更新

db.collection_name.update(<query>,<update>, {multi:<boolean>})
  • 参数query:查询条件
  • 参数update:更新操作符
  • 参数multi:可选,默认是false,表示只更新找到的第一条记录,
  • 值为true表示把模拟组条件的文档全部更新
db.collection_name.update({name:'br'},{name:'hr'}) //更新一条(替换)
db.collection_name.update({name:'br'},{$set:{name:'hr'}}) //更新一条(更新)
db.collection_name.update({},{$set:{gender:0}},{multi:true}) //更新全部

注意:multi update only works with $ operators

删除

db.collection_name.remove(<query>,{justOne:<boolean>})
  • 参数query:可选,删除的文档的条件
  • 参数justOne:可选,如果设为true或1,则只删除一条,默认false,表示删除多条

数据查询

  • 方法find():查询
  db.collection_name.find({条件文档})

例:db.collection_name.find({age:20})

  • 方法findOne():查询,只返回第一个
  db.collection_name.findOne({条件文档})
  • 方法pretty():将结果格式化
  db.集合名称.find({条件文档}).pretty()

比较运算符

  • 等于:默认是等于判断,没有运算符
    -小于:$lt (less than)
  • 小于等于:$lte(less than equal)
  • 大于:$gt (greater than)
    -大于等于:$gte
  • 不等于:$ne
    例:db.collection_name.find({age:{$gte:18}})

范围运算符

使用$in, $nin 判断是否在某个范围呢
查询年龄为18、28的学生

db.collection_name.find({age:{$in:[18,28,38]}})

逻辑运算符

  • and 在json中写多个条件即可
db.collection_name.find({name:"br",age:18})

例:查询年龄大于或等于18,并且性别为true的学生

db.collection_name.find({age:{$gte:18},gender:true})
  • or 使用$or , 值为数组,数组中每个元素为json

例:查询年龄大于18,或性别为false的学生

db.collection_name.find({$or:[{age:{$gt:18}},{gender:false}]})

例: 查询年龄大于18或性别为男生,并且姓名是郭靖

db.collection_name.find({$or:[{age:{$gt:18}},{gender:true}],name:"郭靖"})

支持正则表达式

使用//或$regex编写正则表达式

db.collection_name.find({name:/^abc/})
db.collection_name.find({name:{$regex:"123$"}})

limit 和skip

  • 方法limit():用于读取指定数量的文档
  db.collection_name.find().limit(NUMBER)

查询两条学生信息

db.collection_name.find().limit(2)
  • 方法skip():用于跳过指定数量的文档
db.collection_name.find().skip(NUMBER)
db.collection_name.find().skip(2)
  • 同时使用
    可以实现分页, 后者效率低一些
db.collection_name.find().limit(4).skip(5) 
db.collection_name.skip(5).limit(4) 

自定义查询

使用$where后面写一个函数,返回满足条件的数据
查询年龄大于30的学生

db.collection_name.find({
    $where:function(){
        return this.age>30;
    }
})

我们平时写的都是json格式的命令参数,其实MongoDB可以直接接收js命令的。

投影

在查询到的返回结果中,只选择必要的字段

db.collection_name.find({},{字段名称:1,...})

参数为字段与值,值为1表示显示,值为0不显示
特殊:对于_id列默认是显示的,如果不显示需要明确设置为0,除了_id字段之外的其他字段,如果不显示,不能写为0.否则会报错。

db.collection_name.find({},{_id:0,name:1,gender:1})

排序

方法sort(),用于对集合进行排序

db.collection_name.find().sort({字段:1,...})

参数1为升序排序
参数-1为降序排序
根据性别降序,再根据年龄升序

db.collection_name.find().sort({gender:-1,age:1})

统计个数

方法count()用于统计结果集中文档条数

db.collection_name.find({条件}).count()
db.collection_name.count({条件})

例:

db.collection_name.find({gender:false}).count()
db.collection_name.count({age:{$gt:20},gender:true})

find和count的条件不能同时使用。(不确定,待测试)

消除重复

方法distinct()对数据进行去重

db.collection_name.distinct('去重字段',{条件})
db.collection_name.distinct('hometown',{age:{$gt:18}})

数据的备份和恢复

备份的语法:

mongodump -h dbhost -d dbname -o dbdirectory

-h : 服务器地址,也可以指定端口号(本机可以省略)
-d : 需要备份的数据库名称
-o : 备份的数据存放的位置,此目录中存放着备份出来的数据

mongodump -h localhost:27017 -d test - o ~/testbak

该命令不是在MongoDB的客户端执行的,是在我们操作系统的终端执行的

恢复语法:

mongorestore -h dbhost -d dbname --dir dbdirectory

-h : 服务器地址(本机可以省略)
-d : 需要恢复的数据库实例
--dir : 备份数据所在位置

mongorestore -h localhost:27017 -d test1 --dir ~/testbak

聚合 aggregate

聚合(aggregate)是基于数据处理的聚合管道,每个文档通过一个由多个阶段(stage)组成的管道,可以对每个阶段的管道进行分组、过滤等功能,然后经过一些列的处理,输出相应的结果。

db.collection_name.aggregate({管道:{表达式}})

例:

db.collection_name.aggregate([
    {$match:{status:"A"}},  # stage
    {$group:{_id:"$cust_id",total:{$sum:"$amount"}}}  # stage
])

管道

在mongodb中,文档处理完毕后,通过管道进行下一次处理。常用管道如下几种。

$group:将集合中的文档分组,可用于统计结果

  1. 将集合中的文档分组,可用于统计结果
  2. _id表示分组的依据,使用某个字段的格式为’$字段’
  3. 例1:按照性别进行分组,获取不同组数据的个数和平均年龄
db.collection_name.aggregate(
      {$group:{
               _id:’$gender’,
               counter:{$sum:1},
               avg_age:{$avg:”$age”}
        }}
)

例2:按照hometown进行分组,获取不同组的平均年龄

db.collection_name.aggregate(
      {$group:{
            _id:”$hometown”,
            avg_age:{$avg:”$age”}
      }}
)
  1. group by null
    将集合中所有文档分为一组
    例3:求学生总人数、平均年龄(使用$group统计整个文档)
db.collection_name.aggregate(
      {$group:{
            _id:null,
            count:{$sum:1},
            avg_age:{$avg:”$age”}
      }}
)

注意:

  1. $group对应的字典中有几个键,结果中就有几个键
  2. 分组依据需要放到_id后面
  3. 取不同的字段的值需要使用,gender,$age
  4. 取字段嵌套的字典中的值得时候$_id.country
  5. 能够同时按照多个键进行分组group:{_id:{country:"_id.country",province:"_id.province"},count:{sum:1}}

$match:过滤数据,主输出符合条件的文档

  1. 用于过滤数据,只输出符合条件的文档, 功能等同于find。
  2. match是管道命令,能将结果交给后一个管道,但是find不可以。
  3. 使用MongoDB的标准查询操作
  4. 例1:查询年龄大于20的学生
db.collection_name.aggragate(
  {$match:{age:{$gt:20}}}
)

例2:查询年龄大于20的男生、女生人数

db.collection_name.aggragate(
{$match:{age:{$gt:20}}},
{$group:{_id:”$gender”,counter:{$sum:1}}}
)

例3:

db.collection_name.aggragate(
{$match:{$or:[{age:{$gt:20}},{hometown:{$in[“大理”,”丽江”]}}]}},
{$group:{_id:”$gender”,counter:{$sum:1}}},
{$project:{_id:0,gender:”$_id”,counter:1}}
)

$project:修改输入文档的结构,如重命名、增加、删除字段、创建计算结果

  1. 修改输入文档的结构,如重命名、增加、删除字段、创建计算结果
  2. 例1查询学生的姓名、年龄
db.collection_name.aggregate(
    {$project:{_id:0,name:1,age:1}}
)

例2:查询男生、女生人数,输出人数

db.collection_name.aggragate(
      {$group:{_id:”$gender”,counter:{$sum:1}}},
      {$project:_id:0,counter:1}
)

例3:

db.collection_name.aggregate(
      {$group:{
            _id:’$gender’,
            counter:{$sum:1},
            avg_age:{$avg:”$age”}
      }},
      {$project:{
            gender:”$_id”,
            count:”$count”,
            avg_age:”$avg_age”,
            _id:0
      }}
)

练习:统计出每个country/province下的userid的数量(同一个userid只统计一次)

{"country":"china","province":"sh","userid":"a"}
{"country":"china","province":"sh","userid":"b"}
{"country":"china","province":"sh","userid":"a"}
{"country":"uk","province":"sh","userid":"c"}
{"country":"china","province":"bj","userid":"da"}
{"country":"china","province":"bj","userid":"fa"}
db.collection_name.aggregate({
    $group:{_id:{country:"$country",province:"$province",userid:"$userid"}},
    $group:{_id:{country:"$_id.country",province:"$_id.province"},count:{$sum:1}},
    $project:{country:"$_id.country",province:"$_id.province",count:1,_id:0}
})

$sort:将输入文档排序后输出

  1. 将输入文档排序后输出
  2. 例1:查询学生信息,按年龄排序
db.collection_name.aggregate({
    $sort:{age:1}
})

例2:查询男生、女生人数,按人数降序

db.collection_name.aggregate({
    $group:{_id:"$gender",counter:{$sum:1}}},
    {$sort:{counter:-1}
})

$limit:限制聚合管道返回的文档数

  1. 限制聚合管道返回的文档数
  2. 例1:查询2条学生信息
db.collection_name.aggregate($limit:2)

$skip:跳过指定数量的文档,并返回余下的文档

  1. 跳过指定数量的文档,并返回余下的文档
  2. 例1:查询从第三条开始的学生信息
db.collection_name.aggregate($skip:2)

例2:查询从第三条开始的两条数据

db.collection_name.aggregate({$skip:2},{$limit:2})

例3:统计男生、女生人数,按人数升序,取第二条数据

db.collection_name.aggregate(
    {$group:{_id:"$gender",counter:{$sum:1}}},
    {$sort:{counter:1}},
    {$skip:1},
    {$limit:1}
)

$unwind:将数组类型的字段进行拆分

  1. 将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
  2. 语法:db.collection_name.aggregate({unwind:”字段名称”})
db.collection_name.insert({_id:1,item:"t-shirt",size:["S","M","L"]})
db.collection_name.aggregate({$unwind:"$size"})

结果如下:

{_id:1,item:"t-shirt",size:"S"}
{_id:1,item:"t-shirt",size:"M"}
{_id:1,item:"t-shirt",size:"L"}

练习:数据库中有一条数据:{“username”:”Alex”,”tags”:[‘c#’,’java’,’c++’]},如何获取该tag列表的长度?

db.collection_name.aggregate(
    {$match:{username:"Alex"}}
    {$unwind:"$tags"},
    {$group:{_id:null,sum:{$sum:1}}}
)

属性值为false表示丢弃属性值为空的文档
属性preserveNullAndEmptyArrays值为true表示保留属性值为空的文档
用法:

db.collection_name.aggregate({
    $unwind:{
        path:'$字段名称',
        preserveNullAndEmptyArrays:<boolean> # 防止数据丢失
    }
})

例:

db.collection_name.insert(
    {_id:1,item:"a",size:["S","M","L"]},
    {_id:2,item:"b",size:[ ]},
    {_id:3,item:"bc",size:["S"]},
    {_id:4,item:"d"},
    {_id:5,item:"e",size:null}
)
db.collection_name.aggregate({$unwind:"$size"})
db.collection_name.aggregate({
    $unwind:{
        path:"$size",
        preserveNullAndEmptyArrays:true
    }
})

表达式

处理输入文档并输出
语法:表达式:"$列名"

常用表达式:
$sum:就算总和,$sum:1 表示以一倍计数
$avg:计算平均值
$min:获取最小值
$max:获取最大值
$push:在结果文档中插入值到一个数组中
$first:根据资源文档的排序获取第一个文档数据
$last:根据资源文档的排序获取最后一个文档数据

索引创建

索引:以提升查询速度
测试:插入10万条数据到数据库中

for(i=0;i<100000;i++){db.collection_name.insert({name:'test'+i, age:i})}
db.collection_name.find({name:'test10000'})
db.collection_name.find({name:'test10000'}).explain('executionStats')

建立索引之后对比:
语法:db.collection_name.ensureIndex({属性:1}),1表示升序,-1表示降序
具体操作:

db.collection_name.ensureIndex({name:1})
db.collection_name.find({name:'test10000'}).explain('executionStats'

索引操作

  1. 在默认情况下索引字段的值可以相同
  2. 创建唯一索引(索引的值是唯一的)
db.collection_name.ensureIndex({'name':1},{"unique":true})
  1. 建立联合索引(什么时候需要联合索引)
    多个字段确定一条数据的唯一性
db.collection_name.ensureIndex({name:1,age:1})
  1. 查看当前集合的所有索引
db.collection_name.getIndexes()
  1. 删除索引
db.collection_name.dropIndex("索引名称")

MongoDB MySQL Redis的区别和使用场景

  1. MySQL是关系型数据库,支持事务
  2. MongoDB,Redis非关系型数据库,不支持事务
  3. MySQL MongoDB Redis的实用根据如何方便进行选择
    a) 希望速度快的时候选择MongoDB或者是Redis
    b) 数据量过大的时候,选择频繁使用的数据存入redis,其他的存入MongoDB
    c) MongoDB不用提前建表建数据库,使用方便,字段数据不确定的时候使用MongoDB
    d) 后续需要用到数据之间的关系,此时考虑MySQL

爬虫数据去重,实现增量式爬虫
使用数据库建立关键字字段(一个或者多个)的唯一索引进行去重。
根据URL地址进行去重。

  1. 使用场景
    URL地址对应的数据不会变得情况,URL地址能够唯一判别一条数据的情况
  2. 思路
    URL存在Redis中,拿到URL地址,判断URL在Redis中的URL的集合中是否存在,存在,说明URL已经被请求国,不再请求,不存在,URL地址没有被请求国,请求,把该URL存入Redis集合中
  3. 布隆过滤器
    使用多个加密算法加密URL地址,得到多个值
    往对应值的位置把结果设置为1
    新来一个URL地址,一样通过加密算法生成多个值
    如果对应位置的值全为1,说明这个URL地址已经抓过
    否则没有抓过,就把对应位置的值设置为1
    根据数据本身进行去重
  4. 选择特定的字段,使用加密算法(md5,sha1)将字段进行加密,生成字符串,存入redis集合中
  5. 后续新来一条数据,同样的方法进行加密,如果得到的字符串在Redis中存在,说明数据存在,对数据进行更新,否则说明数据不存在,直接插入。

动手
尝试将我电脑中的douban.tv1中的数据恢复到自己的电脑中,具体如何操作?
完成上述操作后完成以下问题:

  1. 获取每条数据中的title,count(所有评分人数),rate(评分),country(国家的这些字段)
db.collection_name.aggregate(
    {$project:{title:1,_id:0,count:"$rating.count",rate:"$tating.value",country:"$tv_category"}}
)
  1. 获取上述结果中的不同国家电影的数据量
db.collection_name.aggregate(
    {$project:{title:1,_id:0,count:"$rating.count",rate:"$tating.value",country:"$tv_category"}},
    {$group:{_id:"country",count:{$sum:1}}}
)
  1. 获取上述结果中分数大于8分的不同国家电视剧的数据量
db.collection_name.aggregate(
    {$project:{title:1,_id:0,count:"$rating.count",rate:"$tating.value",country:"$tv_category"}},
    ${match:{rate:{$gt:8}}},
    {$group:{_id:"country",count:{$sum:1}}},
    {$project:{_id:0,country:"$_id",count:1}}
)

实例化和插入、更新

from pymongo import MongoClient

class TestMongo:
    def __init__(self):
        # 实例化client 建立连接
        client = MongoClient(host='127.0.0.1', port=27017)
        # client[数据库][集合]
        self.collection = client["test"]["t1"]  # 使用方括号的方式选择数据库和集合

    # 插入一条数据
    def test_insert(self):
        # insert接收字典,返回objectId
        ret = self.collection.insert({name:"test1000",age:33})
        print(ret)

    # 插入多条数据
    def test_insert_many(self):
        item_list = [{name:"test1000{}".format(i)} for i in range(10)]
        # insert_many接收一个列表,列表中为所有需要插入的字典
        t = self.collection.insert_many(item_list)
        # t.inserted_ids为所有插入的id
        for i in t.inserted_ids:
            print(i)

    def try_find_one(self):
        # find_one查找并且返回一个结果,接收一个字典形式的条件
        t = self.collection.find_one({name:"test1000"})
        print(t)

    def try_find(self):
        # 查询所有
        t = collection.find()
        for i in t:
            print(i)

    def try_find_many(self):
        # find返回所有满足条件的结果,如果条件为空,则返回数据库的所有
        t = self.collection.find({name:"test1111"})
        # 结果是一个cursor游标对象,是一个可迭代对象,可以类似读文件的指针
        for i in t:
            print(i)
        for i in t: #此时t中没有内容
            print(i)

    def try_update_one(self):
        # update_one更新一条数据
        self.collection.update_one({name:"test2"},{$set:{name:new_test11}})

    def try_update_many(self):
        # update_many更新全部数据
        self.collection.update_many({name:"test111"},{$set:{name:"new_test222"}})

    def try_delete_one(self):
        # delete_one删除一条数据
        self.collection.delete_one({name:"test10010"})

    def try_delete_many(self):
        # delete_many删除所有满足条件的数据
        self.collection.delete_many({name:"test10010"})

练习:

  1. 使用Python想集合t3中插入1000条文档,文档的属性包括_id、name
    a) _id的值为0、1、2、3……999
    b) Name的值为py0、py1……
data_list = [ {"_id":i,"name":"py{}".format(i)} for i in range(1000) ]
collection.insert_many(data_list)
  1. 查询显示出_id为100的整倍数的文档,如100、200、300……, 并将name输出
ret = collection.find()
data_list = list(ret)
data_list = [i for i in data_list if i["_id"]%100==0 and i["_id"]!=0]
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容

  • Mongodb的特点: 模式自由:可以把不同结构的文档存储在同一个数据库里 面向集合的储存:适合储存JSON风格文...
    姓高名旭升阅读 723评论 0 0
  • 简介 MongoDB 是一个基于分布式文件存储的NoSQL数据库 由C++语言编写,运行稳定,性能高 旨在为 WE...
    大熊_7d48阅读 33,191评论 1 8
  • 首先安装好 MongoDB 数据库并启动它,然后进入用 CMD 命令进入到 ${MONGODB_HOME}/bin...
    本宫在丶尔等都是妃阅读 417评论 0 2
  • 安装 MongoDB Windowns、Ubuntu17.10 下安装 MongoDB教程在此 MongoDB 帮...
    Kangvcar阅读 2,061评论 0 13
  • Mongodb的特点: 模式自由:可以把不同结构的文档存储在同一个数据库里 面向集合的储存:适合储存JSON风格文...
    浮_屠阅读 2,579评论 0 0