/*
 查看所有数据库信息
*/
show dbs

/*
创建数据库,如果第一次创建是不会显示的,需要插入数据才行,如果数据库存在的话,那么就表示进入该数据库的意思
*/
use my_mon

/*
查看集合

*/
show collection;
/*
    name:集合名称
    options:该集合的属性:
              capped:是否启用集合限制,如果开启需要制定一个限制条件,默认为不启用,这个参数没有实际意义
          size:限制集合使用空间的大小,默认为没有限制
          max:集合中最大条数限制,默认为没有限制
          autoIndexId:是否使用_id作为索引,默认为使用(true或false)
          size的优先级比max要高
*/
#创建集合
db.createCollection('stus')

/*
向集合插入数据  insert
   如果没有明确规定唯一主键,那就会自动生成_id ,来确保数据的唯一性
   可以通过ObjectId() 可以获取这个唯一主键
   单条插入 insertOne()
   批量插入 insertMany()
   他们的区别,就仅仅是寓意上面的区别,类似java中方法重写的含义
*/
#插入语句--单条插入 类似JSON文档,但是还是有区别
db.stus.insert({name:"陈蕾",age:26,gender:"女性"});

#插入语句--批量插入
db.stus.insert([
    {name:"张三",age:26,gender:"男性"},
    {name:"李四",age:26,gender:"男性"},
    {name:"牛翠花",age:26,gender:"女性"}
]);
#指定_id 
db.stus.insert({_id:"lvxiwei",name:"吕习伟",age:26,gender:"女性"});

/*
  查询 db.Collection.find()
          find() --查询该集合下所有数据的一个数组,通过跟随[index]查询index下标的数据,通常可以表示find()[0]==findOne()
        条件查询:
                 类似于MySQL中的where语句 
                     语法:find({属性:属性值})
          findOne() --用于查找所有符合条件的数据第一个数据,返回的是一个对象,通常可以表示findOne().name
            find().count() --查询所有结果的数量
            find().lenth() --查询所有结果的数量

*/

#查询
db.stus.find()
#条件查询
db.stus.find({_id:"lvxiwei"})

/*
修改:db.collection.update(查询条件,新对象,修改条件)
    如果不添加指定修改属性,那么新对象就会直接覆盖原对象
        通过set来修改指定的属性值

*/
#整体覆盖,会把该id下的对象,直接覆盖成{_id:"lvxiwei",age:27}
db.stus.update({_id:"lvxiwei"},{age:27})
#指定属性修改
db.stus.update(
    {_id:"lvxiwei"},
    {$set:{
                    gender:"男性",
                    address:"南京江宁"
                }
    }
)

#删除某一个属性 unset操作不匹配属性值,只匹配属性名,意思就跟你后面的属性值是没关系的,直接把该属性给删除
db.stus.update(
    {_id:"lvxiwei"},
    {$unset:{
                    address:"南京江宁"
                }
    }
)

#修改多条数据使用Many
db.stus.updateMany(
    {name:"xxx"},
    {$set:{
                    gender:"男性",
                    address:"南京江宁"
                }
    }
)
#多条替换 multi来决定执行单条还是多条
db.stus.update(
    {_id:"lvxiwei"},
    {$set:{
                    gender:"男性",
                    address:"南京江宁"
                }
    },
    {
        multi:true
    }

)

/*
    删除 
        语法:remove() 单条或者多条
                    deleteOne() 单条
                    deleteMany() 多条


*/
#默认删除符合条件的所有数据 
db.stus.remove({_id:"lvxiwei"})


#justOne=true时候,默认删除该条件下第一条数据
db.stus.remove({age:11},true)


#如果remove() 不跟任何参数,那就属于清空stus这个集合,性能差 ,因为他是一条一条删除
db.stus.remove()

/*
    删除集合 drop()
    这个方法需要注意使用,如果test这个数据库只有一个stus集合,如果你使用这个命令,那么test就也没了
    但是清空集合的性能上,比remove的速度快的不是一星半点,因为remove伴随遍历删除,而drop不存在遍历
*/
db.stus.drop()

/*
删除数据库 dropDatabase()
*/
db.dropDatabase()

#对于DBA来说,删除的方法少用,因为数据一旦删除,就意味着在磁盘中消失了,
#一旦删除,可能会造成无法估量的后果,无论关系型或者非关系型数据库,我们在开发中
#尽量采用假删除,通过数据的某一个字段的属性进行更改,通过查询条件来限制
#如果数据对你来说也无所谓,也可以随便删除
#非关系数据,在项目中基本用于缓存使用,辅助关系型数据库,来减轻关系型数据库的压力
/*
嵌套文档:属性值也可以是文档,类似于java中的内部类
*/

#内嵌文档
db.stus.insert({
        _id:"ipad-Air-2",
        name:"苹果平板第五代",
        age:5,
        gender:"none",
        address:{
                            monthland:"美国",
                            city:"DC 华盛顿",
                            company:"苹果公司",
                            author:"乔布斯"
                        }
})

db.stus.find({_id:"ipad-Air-2"})


db.stus.update(
    {_id:"lvxiwei"},
    {$set:{
                address:{
                            monthland:"中国",
                            city:"南京",
                            author:"none"
                                }
            }
    }
)


db.stus.find({_id:"lvxiwei"})

#内嵌文档查询方式 类似于java中面向对象,通过.的方式后来获取成员属性 
db.stus.find({'address.city':'南京'})

#内嵌文档可以插入数组文档
db.stus.update(
        {name:"陈蕾"},
        {$set:{
                movies:["喜羊羊和灰太狼","三生三世之十里桃花","天线宝宝"]
                    }
        }
)
db.stus.find({name:"陈蕾"})

/*
数组文档
*/
#添加数组内元素 末尾追加(不会考虑重复元素) $push
db.stus.update(
    {name:"陈蕾"},
    {$push:{
            movies:"小猪佩奇"
    }})
#添加数组内元素 考虑重复元素,如果存在,就不会添加 $addToSet
db.stus.update(
    {name:"陈蕾"},
    {$addToSet:{
            movies:"小猪佩奇"
    }})

/*
    循环插入文档 内存8G 512SSD  执行时间10.866s
*/
#执行20000次insert
for (var i = 0; i <20000; i++) {
    db.numbers.insert({num:i+1})
}
db.numbers.remove({})
#执行1次insert ,但是数据还是20000万条   0.85s  这就是差距
var arr = [];
for (var i = 0; i < 20000; i++) {
    arr.push({num:i});
}
db.numbers.insert(arr);
/*
    查询比较符号:
*/
#查询numbers中大于500  $gt >
db.numbers.find({num:{$gt:500}})

#查询numbers中大于等于500  $gte >=
db.numbers.find({num:{$gte:500}})

#查询numbers中等于500  $eq = 
db.numbers.find({num:{$eq:500}})

#查询numbers中小于500  $lt <
db.numbers.find({num:{$lt:500}})

#查询numbers中大于500,小于10000   < x <
db.numbers.find({num:{$gt:500,$lt:10000}})

#如果查询数据是随机大小,但是需要限制条数  通常我们在查询中,应该考虑性能问题 其实这里的limit的逻辑是MySQL是差不多的
db.numbers.find().limit(10)

#分页数据显示10-20  limit(pageCount) 和skip(pageNum)
db.numbers.find().skip(10).limit(10)

#如果看到limit 和skip的位置不对,是正常,mongo会帮我们自动校准语句语序