zoukankan      html  css  js  c++  java
  • MongoDB 的 curd 操作

    1 数据库的curd操作

    # 增加
    use test   # 有就进去,没有就创建并进去
    db.t1.insert({"name":"lqz"})  # 库,集合,文档全都进去了
    
    # 查询
    show databases;
    show dbs
    
    # 删除
    use test #先切换到要删的库下
    db.dropDatabase() #删除当前库
    

    2 集合操作

    # 新增
    use test
    db.table1.insert({"name":"lqz"}) # 有就使用,没有就新增
    db.table2.insert({'b':2})
    # 查询
    show tables
    show collections
    # 删除
    db.table1.drop()
    
    

    3 文档操作(curd)

    新增和修改

    #单条插入与多条插入
    
    #1、没有指定_id则默认ObjectId,_id不能重复,且在插入后不可变
    
    #2、插入单条
    user0={
        "name":"lqz",
        "age":10,
        'hobbies':['music','read','dancing'],
        'addr':{
            'country':'China',
            'city':'BJ'
        }
    }
    
    db.test.insert(user0)
    db.test.find()
    
    #3、插入多条
    user1={
        "_id":1,
        "name":"lqz1",
        "age":10,
        'hobbies':['music','read','dancing'],
        'addr':{
            'country':'China',
            'city':'weifang'
        }
    }
    
    user2={
        "_id":2,
        "name":"lqz2",
        "age":20,
        'hobbies':['music','read','run'],
        'addr':{
            'country':'China',
            'city':'hebei'
        }
    }
    
    user3={
        "_id":3,
        "name":"lqz3",
        "age":30,
        'hobbies':['music','drink'],
        'addr':{
            'country':'China',
            'city':'heibei'
        }
    }
    
    user4={
        "_id":4,
        "name":"lqz4",
        "age":40,
        'hobbies':['music','read','dancing','tea'],
        'addr':{
            'country':'China',
            'city':'BJ'
        }
    }
    
    user5={
        "_id":5,
        "name":"lqz5",
        "age":50,
        'hobbies':['music','read',],
        'addr':{
            'country':'China',
            'city':'henan'
        }
    }
    db.user.insertMany([user1,user2,user3,user4,user5])
    
    # 有则覆盖,没则新增(覆盖更新)
    db.user.save({"_id":1,"name":"lqzxxx"})
    db.user.save("name":"lqz"})
    

    查询文档

    # 比较运算
    # SQL:=,!=,>,<,>=,<=
    # MongoDB:{key:value}代表什么等于什么,"$ne","$gt","$lt","gte","lte",其中"$ne"能用于所有数据类型
    db.user.find().pretty()  # 以json格式显示,了解
    #1、select * from db1.user where name = "lqz1";
    db.user.find({'name':'lqz1'})
    
    #2、select * from db1.user where name != "lqz2";
    db.user.find({'name':{"$ne":'lqz2'}})
    
    #3、select * from db1.user where id > 2;
    db.user.find({'_id':{'$gt':2}})
    
    #4、select * from db1.user where id < 3;
    db.user.find({'_id':{'$lt':3}})
    
    #5、select * from db1.user where id >= 2;
    db.user.find({"_id":{"$gte":2,}})
    
    #6、select * from db1.user where id <= 2;
    db.user.find({"_id":{"$lte":2}})
    
    
    

    逻辑运算

    #逻辑运算
    # SQL:and,or,not ,mod(取余数)
    # MongoDB:字典中逗号分隔的多个条件是and关系,"$or"的条件放到[]内,"$not"
    
    #1、select * from db1.user where id >= 2 and id < 4;
    db.user.find({'_id':{"$gte":2,"$lt":4}})
    
    #2、select * from db1.user where id >= 2 and age < 40;
    db.user.find({"_id":{"$gte":2},"age":{"$lt":40}})
    
    #3、select * from db1.user where id >= 5 or name = "lqz";
    db.user.find({
        "$or":[
            {'_id':{"$gte":5}},
            {"name":"lqz"}
            ]
    })
    
    
    #4、select * from db1.user where id % 2=1;
    db.user.find({'_id':{"$mod":[2,1]}})
    
    #5、上题,取反
    db.user.find({'_id':{"$not":{"$mod":[2,1]}}})
    
    

    成员运算

    # 成员运算
    # SQL:in,not in
    # MongoDB:"$in","$nin"
    
    #1、select * from db1.user where age in (20,30,31);
    db.user.find({"age":{"$in":[20,30,31]}})
    
    #2、select * from db1.user where name not in ('lqz1','lqz2');
    db.user.find({"name":{"$nin":['lqz1','lqz2']}})
    
    

    正则匹配

    # SQL: regexp 正则
    # MongoDB: /正则表达/i
    #1、select * from db1.user where name regexp '^l';
    # 查询名字以l开头的人
    db.user.find({"name":/.*?/})
    db.user.find({"name":/^l/})
    # 查询名字以l开头,以1结尾的所有数据
    db.user.find({"name":/^l.*?1$/})
    

    取指定字段

    #1、select name,age from db1.user where id=3;
    db.user.find({'_id':3},{'_id':0,'name':1,'age':1})
    # 0表示不显示,1表示显示
    

    查询数组

    #1、查看有dancing爱好的人
    db.user.find({'hobbies':'dancing'})
    
    #2、查看既有dancing爱好又有tea爱好的人
    db.user.find({
        'hobbies':{
            "$all":['dancing','tea']
            }
    })
    
    #3、查看第4个爱好为tea的人
    db.user.find({"hobbies.3":'tea'})
    
    #4、查看所有人最后两个爱好(注意没有hobbies字段的也会被查出)(本质用的是取指定字段,所以要放在后面的字典中)
    db.user.find({},{'hobbies':{"$slice":-2},"age":0,"_id":0,"name":0,"addr":0})
    
    #5、查看所有人的第2个到第3个爱好
    db.user.find({},{'hobbies':{"$slice":[1,2]},"age":0,"_id":0,"name":0,"addr":0})
    
    > db.blog.find().pretty()
    {
            "_id" : 1,
            "name" : "alex意外死亡的真相",
            "comments" : [
                    {
                            "name" : "egon",
                            "content" : "alex是谁???",
                            "thumb" : 200
                    },
                    {
                            "name" : "wxx",
                            "content" : "我去,真的假的",
                            "thumb" : 300
                    },
                    {
                            "name" : "yxx",
                            "content" : "吃喝嫖赌抽,欠下两个亿",
                            "thumb" : 40
                    },
                    {
                            "name" : "egon",
                            "content" : "xxx",
                            "thumb" : 0
                    }
            ]
    }
    db.blog.find({},{'comments':{"$slice":-2}}).pretty() #查询最后两个
    db.blog.find({},{'comments':{"$slice":[1,2]}}).pretty() #查询1到2
    

    排序

    # 排序:--1代表升序,-1代表降序
    db.user.find().sort({"name":1,})
    db.user.find().sort({"age":-1,'_id':1})
    

    分页

    # 分页:--limit代表取多少个document,skip代表跳过前多少个document。 
    # limit中表示一页显示的条数,skip(页码数*一页显示的条数)
    db.user.find().sort({'age':1}).limit(1).skip(2)
    
    
    # 表关联
    user {_id:1,name:lqz,age:18}   一个人写多篇文章
    article ----》子查询
    	{'userid':1,article:红楼梦}
      {'userid':1,article:西游记}
    

    获取数量

    # 获取数量
    db.user.count({'age':{"$gt":30}}) 
    --或者
    db.user.find({'age':{"$gt":30}}).count()
    

    其他

    #1、{'key':null} 匹配key的值为null或者没有这个key
    db.t2.insert({'a':10,'b':111})
    db.t2.insert({'a':20})
    db.t2.insert({'b':null})
    
    > db.t2.find({"b":null})
    { "_id" : ObjectId("5a5cc2a7c1b4645aad959e5a"), "a" : 20 }
    { "_id" : ObjectId("5a5cc2a8c1b4645aad959e5b"), "b" : null }
    
    #2、查找所有
    db.user.find() #等同于db.user.find({})
    db.user.find().pretty()
    
    #3、查找一个,与find用法一致,只是只取匹配成功的第一个
    db.user.findOne({"_id":{"$gt":3}})
    
    

    修改文档

    语法介绍

    update() 方法用于更新已存在的文档。语法格式如下:
    db.collection.update(
       <query>,
       <update>,
       {
         upsert: <boolean>,
         multi: <boolean>,
         writeConcern: <document>
       }
    )
    参数说明:对比update db1.t1 set name='EGON',sex='Male' where name='egon' and age=18;
    
    db.collection.update(
       {name:{$ne:lqz}},
       {字典},
       {
         upsert: <boolean>,
         multi: <boolean>,
         writeConcern: <document>
       }
    )
    query : 相当于where条件。
    update : update的对象和一些更新的操作符(如$,$inc...等,相当于set后面的
    upsert : 可选,默认为false,代表如果不存在update的记录不更新也不插入,设置为true代表插入。
    multi : 可选,默认为false,代表只更新找到的第一条记录,设为true,代表更新找到的全部记录。
    writeConcern :可选,抛出异常的级别。
    
    更新操作是不可分割的:若两个更新同时发送,先到达服务器的先执行,然后执行另外一个,不会破坏文档。
    

    覆盖式

    #注意:除非是删除,否则_id是始终不会变的
    #1、覆盖式:
    db.user.update({'age':30},{"name":"lqz9","hobbies_count":3})
    是用{"_id":3,"name":"lqz3","hobbies_count":3}覆盖原来的记录
    
    #2、一种最简单的更新就是用一个新的文档完全替换匹配的文档。这适用于大规模式迁移的情况。例如
    var obj=db.user.findOne({"_id":4})
    
    obj.username=obj.name+'NB'
    obj.hobbies_count++
    delete obj.age
    delete obj._id
    
    db.user.update({"_id":2},obj)
    

    设置$set

    #设置:$set
    
    通常文档只会有一部分需要更新。可以使用原子性的更新修改器,指定对文档中的某些字段进行更新。
    更新修改器是种特殊的键,用来指定复杂的更新操作,比如修改、增加后者删除
    
    #1、update db1.user set  name="张三" where id = 2
    db.user.update({'_id':2},{"$set":{"name":"张三",}})
    
    #2、没有匹配成功则新增一条{"upsert":true}
    db.user.update({'_id':6},{"$set":{"name":"李飞刀","age":18}},{"upsert":true})
    
    #3、默认只改匹配成功的第一条,{"multi":改多条}
    db.user.update({'_id':{"$gt":4}},{"$set":{"age":28}})
    db.user.update({'_id':{"$gte":4}},{"$set":{"age":38}},{"multi":true})
    
    #4、修改内嵌文档,把名字为lqz4的人所在的地址国家改成Japan
    db.user.update({'name':"lqz4"},{"$set":{"addr.country":"Japan"}})
    
    #5、把名字为lqz4的人的第2个爱好改成sleep
    db.user.update({'name':"lqz4"},{"$set":{"hobbies.1":"sleep"}})
    
    #6、删除lqz4的爱好,$unset
    db.user.update({'name':"lqz4"},{"$unset":{"hobbies":""}})
    

    增加和减少

    #增加和减少:$inc
    
    #1、所有人年龄增加一岁
    db.user.update({},
        {
            "$inc":{"age":1}
        },
        {
            "multi":true
        }
        )
    #2、所有人年龄减少5岁
    db.user.update({},
        {
            "$inc":{"age":-5}
        },
        {
            "multi":true
        }
        )
    

    添加删除组内元素 $push $pop $pull

    #添加删除数组内元素
        
    往数组内添加元素:$push
    #1、为名字为lqz的人添加一个爱好read
    db.user.update({"name":"lqz"},{"$push":{"hobbies":"read"}})
    
    #2、为名字为lqz的人一次添加多个爱好tea,dancing
    db.user.update({"name":"lqz"},{"$push":{
        "hobbies":{"$each":["tea","dancing"]}
    }})
    
    按照位置且只能从开头或结尾删除元素:$pop
    #3、{"$pop":{"key":1}} 从数组末尾删除一个元素
    
    db.user.update({"name":"lqz"},{"$pop":{
        "hobbies":1}
    })
    
    #4、{"$pop":{"key":-1}} 从头部删除
    db.user.update({"name":"lqz"},{"$pop":{
        "hobbies":-1}
    })
    
    #5、按照条件删除元素,:"$pull" 把符合条件的统统删掉,而$pop只能从两端删
    # 删除所有国家为chine的人的read爱好
    db.user.update({'addr.country':"China"},{"$pull":{
        "hobbies":"read"}
    },
    {
        "multi":true
    }
    )
    

    避免重复 "$addToSet"

    #避免添加重复:"$addToSet"
    
    db.urls.insert({"_id":1,"urls":[]})
    
    db.urls.update({"_id":1},{"$addToSet":{"urls":'http://www.baidu.com'}})
    db.urls.update({"_id":1},{"$addToSet":{"urls":'http://www.baidu.com'}})
    db.urls.update({"_id":1},{"$addToSet":{"urls":'http://www.baidu.com'}})
    
    db.urls.update({"_id":1},{
        "$addToSet":{
            "urls":{
            "$each":[
                'http://www.baidu.com',
                'http://www.baidu.com',
                'http://www.xxxx.com'
                ]
                }
            }
        }
    )
    

    其他

    #1、了解:限制大小"$slice",只留最后n个
    
    db.user.update({"_id":5},{
        "$push":{"hobbies":{
            "$each":["read",'music','dancing'],
            "$slice":-2
        }
        }
    })
    
    #2、了解:排序The $sort element value must be either 1 or -1"
    db.user.update({"_id":5},{
        "$push":{"hobbies":{
            "$each":["read",'music','dancing'],
            "$slice":-1,
            "$sort":-1
        }
        }
    })
    
    #注意:不能只将"$slice"或者"$sort"与"$push"配合使用,且必须使用"$eah"
    

    5.3.4 删除文档

    #1、删除多个中的第一个
    db.user.deleteOne({ 'age': 8 })
    
    #2、删除国家为China的全部
    db.user.deleteMany( {'addr.country': 'China'} ) 
    
    #3、删除全部
    db.user.deleteMany({}) 
    

    5.3.5 聚合

    如果你有数据存储在MongoDB中,你想做的可能就不仅仅是将数据提取出来那么简单了;你可能希望对数据进行分析并加以利用。MongoDB提供了以下聚合工具:
    #1、聚合框架
    #2、MapReduce(详见MongoDB权威指南)
    #3、几个简单聚合命令:count、distinct和group。(详见MongoDB权威指南)
    
    #聚合框架:
    可以使用多个构件创建一个管道,上一个构件的结果传给下一个构件。
    这些构件包括(括号内为构件对应的操作符):筛选($match)、投射($project)、分组($group)、排序($sort)、限制($limit)、跳过($skip)
    不同的管道操作符可以任意组合,重复使用
    

    准备数据

    from pymongo import MongoClient
    import datetime
    
    client=MongoClient('mongodb://root:123@localhost:27017')
    table=client['db1']['emp']
    # table.drop()
    
    l=[
    ('egon','male',18,'20170301','老男孩驻沙河办事处外交大使',7300.33,401,1), #以下是教学部
    ('alex','male',78,'20150302','teacher',1000000.31,401,1),
    ('wupeiqi','male',81,'20130305','teacher',8300,401,1),
    ('yuanhao','male',73,'20140701','teacher',3500,401,1),
    ('liwenzhou','male',28,'20121101','teacher',2100,401,1),
    ('jingliyang','female',18,'20110211','teacher',9000,401,1),
    ('jinxin','male',18,'19000301','teacher',30000,401,1),
    ('成龙','male',48,'20101111','teacher',10000,401,1),
    
    ('歪歪','female',48,'20150311','sale',3000.13,402,2),#以下是销售部门
    ('丫丫','female',38,'20101101','sale',2000.35,402,2),
    ('丁丁','female',18,'20110312','sale',1000.37,402,2),
    ('星星','female',18,'20160513','sale',3000.29,402,2),
    ('格格','female',28,'20170127','sale',4000.33,402,2),
    
    ('张野','male',28,'20160311','operation',10000.13,403,3), #以下是运营部门
    ('程咬金','male',18,'19970312','operation',20000,403,3),
    ('程咬银','female',18,'20130311','operation',19000,403,3),
    ('程咬铜','male',18,'20150411','operation',18000,403,3),
    ('程咬铁','female',18,'20140512','operation',17000,403,3)
    ]
    
    for n,item in enumerate(l):
        d={
            "_id":n,
            'name':item[0],
            'sex':item[1],
            'age':item[2],
            'hire_date':datetime.datetime.strptime(item[3],'%Y%m%d'),
            'post':item[4],
            'salary':item[5]
        }
        table.save(d)
    

    筛选 "$match"

    {"$match":{"字段":"条件"}},可以使用任何常用查询操作符$gt,$lt,$in等
    
    #例1、select * from db1.emp where post='teacher';
    db.emp.aggregate({"$match":{"post":"teacher"}}) # shell版本不匹配,会出错
    
    #例2、select * from db1.emp where id > 3 group by post;  
    # 计算每个部门的平均工资
    select post as _id,avg(salary) as avg_salary from db1.emp where id > 3 group by post;  
    db.emp.aggregate(
        {"$match":{"_id":{"$gt":3}}},
        {"$group":{"_id":"$post",'avg_salary':{"$avg":"$salary"}}}
    )
    
    #例3、select post as _id,avg(salary) as avg_salary from db1.emp where id > 3 group by post having avg(avg_salary) > 10000; 
    # 查询平均工资大于10000的部门
    db.emp.aggregate(
        {"$match":{"_id":{"$gt":3}}},
        {"$group":{"_id":"$post",'avg_salary':{"$avg":"$salary"}}},
        {"$match":{"avg_salary":{"$gt":10000}}}
    )
    

    投射 $project

    {"$project":{"要保留的字段名":1,"要去掉的字段名":0,"新增的字段名":"表达式"}}
    
    #1、select name,post,(age+1) as new_age from db1.emp;
    db.emp.aggregate(
        {"$project":{
            "name":1,
            "post":1,
            "new_age":{"$add":["$age",1]}
            }
    })
    
    #2、表达式之数学表达式
    {"$add":[expr1,expr2,...,exprN]} #相加
    {"$subtract":[expr1,expr2]} #第一个减第二个
    {"$multiply":[expr1,expr2,...,exprN]} #相乘
    {"$divide":[expr1,expr2]} #第一个表达式除以第二个表达式的商作为结果
    {"$mod":[expr1,expr2]} #第一个表达式除以第二个表达式得到的余数作为结果
    
    #3、表达式之日期表达式:$year,$month,$week,$dayOfMonth,$dayOfWeek,$dayOfYear,$hour,$minute,$second
    #例如:select name,date_format("%Y") as hire_year from db1.emp
    db.emp.aggregate(
        {"$project":{"name":1,"hire_year":{"$year":"$hire_date"}}}
    )
    
    #例如查看每个员工的工作多长时间
    db.emp.aggregate(
        {"$project":{"name":1,"hire_period":{
            "$subtract":[
                {"$year":new Date()},
                {"$year":"$hire_date"}
            ]
        }}}
    )
    
    
    #4、字符串表达式
    {"$substr":[字符串/$值为字符串的字段名,起始位置,截取几个字节]}
    {"$concat":[expr1,expr2,...,exprN]} #指定的表达式或字符串连接在一起返回,只支持字符串拼接
    {"$toLower":expr}
    {"$toUpper":expr}
    
    db.emp.aggregate( {"$project":{"NAME":{"$toUpper":"$name"}}})
    
    # 除egon外,所有人名字加SB
    
    db.emp.aggregate(
        {"$match":{"name":{"$ne":"egon"}}},
        {"$project":
            {"_id":0,"new_name":
                {"$concat":
                    ["$name","SB"]
                    }  
                }}            
    )
    # 取除egon外, 所有人名字3个字节(utf8编码,3个字节一个汉字)
    db.emp.aggregate(
        {"$match":{"name":{"$ne":"egon"}}},
        {"$project":
            {"_id":0,"new_name":
                {"$substr":
                    ["$name",0,3]
                    }  
                }}            
    )
    

    分组 $group

    {"$group":{"_id":分组字段,"新的字段名":聚合操作符}}
    
    #1、将分组字段传给$group函数的_id字段即可
    {"$group":{"_id":"$sex"}} #按照性别分组
    {"$group":{"_id":"$post"}} #按照职位分组
    {"$group":{"_id":{"state":"$state","city":"$city"}}} #按照多个字段分组,比如按照州市分组
    
    #2、分组后聚合得结果,类似于sql中聚合函数的聚合操作符:$sum、$avg、$max、$min、$first、$last
    #例1:select post,max(salary) as max_salary from db1.emp group by post; 
    db.emp.aggregate({"$group":{"_id":"$post","max_salary":{"$max":"$salary"}}})
    
    #例2:去每个部门最大薪资与最低薪资
    db.emp.aggregate({"$group":{"_id":"$post","max_salary":{"$max":"$salary"},"min_salary":{"$min":"$salary"}}})
    
    #例3:如果字段是排序后的,那么$first,$last会很有用,比用$max和$min效率高
    db.emp.aggregate({"$group":{"_id":"$post","first_id":{"$first":"$_id"}}})
    
    #例4:求每个部门的总工资
    db.emp.aggregate({"$group":{"_id":"$post","count":{"$sum":"$salary"}}})
    
    #例5:求每个部门的人数
    seledt count(1) as count from emp;
    db.emp.aggregate({"$group":{"_id":"$post","count":{"$sum":1}}})
    
    #3、数组操作符
    {"$addToSet":expr}:不重复
    {"$push":expr}:重复
    
    #例:查询岗位名以及各岗位内的员工姓名:select post,group_concat(name) from db1.emp group by post;
    db.emp.aggregate({"$group":{"_id":"$post","names":{"$push":"$name"}}})
    # 跟上面一样
    db.emp.aggregate({"$group":{"_id":"$post","names":{"$addToSet":"$name"}}})
    

    排序$sort 限制 $limit 跳过 $skip

    {"$sort":{"字段名":1,"字段名":-1}} #1升序,-1降序
    {"$limit":n} 
    {"$skip":n} #跳过多少个文档
    
    #例1、取平均工资最高的前两个部门
    db.emp.aggregate(
    {
        "$group":{"_id":"$post","平均工资":{"$avg":"$salary"}}
    },
    {
        "$sort":{"平均工资":-1}
    },
    {
        "$limit":2
    }
    )
    #例2、
    db.emp.aggregate(
    {
        "$group":{"_id":"$post","平均工资":{"$avg":"$salary"}}
    },
    {
        "$sort":{"平均工资":-1}
    },
    {
        "$limit":3
    },
    {
        "$skip":1
    }
    )
    
    db.emp.aggregate(
    {
        "$group":{"_id":"$post","平均工资":{"$avg":"$salary"}}
    },
    {
        "$sort":{"平均工资":-1}
    },
      {
        "$skip":2
    },
    {
        "$limit":2
    }
    )
    

    随机选取 $sample

    #集合users包含的文档如下
    db.users.insertMany([
    { "_id" : 1, "name" : "dave123", "q1" : true, "q2" : true },
    { "_id" : 2, "name" : "dave2", "q1" : false, "q2" : false  },
    { "_id" : 3, "name" : "ahn", "q1" : true, "q2" : true  },
    { "_id" : 4, "name" : "li", "q1" : true, "q2" : false  },
    { "_id" : 5, "name" : "annT", "q1" : false, "q2" : true  },
    { "_id" : 6, "name" : "li", "q1" : true, "q2" : true  },
    { "_id" : 7, "name" : "ty", "q1" : false, "q2" : true  }
    
    ])
    
    #下述操作时从users集合中随机选取3个文档
    # 抽奖
    db.users.aggregate(
       [ { $sample: { size: 1 } } ]
    )
    
    # 路飞项目搞活动,送优惠券---》3天后开奖---》100---》抽奖成功
    
  • 相关阅读:
    1.27
    1.25
    Representation Learning with Contrastive Predictive Coding
    Learning a Similarity Metric Discriminatively, with Application to Face Verification
    噪声对比估计(负样本采样)
    Certified Adversarial Robustness via Randomized Smoothing
    Certified Robustness to Adversarial Examples with Differential Privacy
    Dynamic Routing Between Capsules
    Defending Adversarial Attacks by Correcting logits
    Visualizing Data using t-SNE
  • 原文地址:https://www.cnblogs.com/kai-/p/12925889.html
Copyright © 2011-2022 走看看