MongoDB修改与聚合二

1.修改方法

一 语法
    里面有三个大的语句:一个是查询条件;一个是修改字段;一个是其他参数(目前就有两个)
    db.table.update(
    条件,
    修改字段,
    其他参数
    )


    update db1.t1 set id=10 where name="egon";#这是sql语句的更新使用

    db.table.update(
    {},#这是查询条件
    {"age":11},
    {
        "multi":true,#这是删除查询到的所有数据
        "upsert":true#这是如果找不到这个数据,就新插入
    }
    )

    1、update db1.user set age=23,name="武大郎" where name="wupeiqi";
    #覆盖式更新就是替换掉查询到的数据,只能替换掉一个查询数据
    db.user.update(
        {"name":"wupeiqi"},
        {"age":23,"name":"武大郎"}
    )
    #局部修改:$set就是只更改这里面显示的字段。
    db.user.update(
        {"name":"alex"},
        {"$set":{"age":73,"name":"潘金莲-alex"}}
    )

    #改多条
    db.user.update(
        {"_id":{"$gte":1,"$lte":2}},
        {"$set":{"age":53,}},
        {"multi":true}
    )
    #有则修改,无则添加
    db.user.update(
        {"name":"EGON"},
        {"$set":{"name":"EGON","age":28,}},
        {
        "multi":true,
        "upsert":true
        }#这个就是参数
    )

    #修改嵌套文档
    db.user.update(
        {"name":"潘金莲-alex"},
        {"$set":{"addr.country":"Japan"}}#如果需要查询到里面有嵌套的数据用.就可以查到。
    )

    #修改数组
    db.user.update(
        {"name":"潘金莲-alex"},
        {"$set":{"hobbies.1":"Piao"}}#如果需要查询到里面有嵌套的数据用.就可以查到。
    )

    #删除字段
    db.user.update(
        {"name":"潘金莲-alex"},
        {"$unset":{"hobbies":""}}#删除一个字段
    )

    2、$inc
    db.user.update(
        {},
        {"$inc":{"age":1}},#增加用的,如果是正数就说明是增加,如果是负数,就是减少
        {"multi":true}
    )

    db.user.update(
        {},
        {"$inc":{"age":-10}},
        {"multi":true}
    )

    3、$push, $pop  $pull#对某个字段的添加或删除
    db.user.update(
        {"name":"yuanhao"},
        {"$push":{"hobbies":"tangtou"}},#对某一个字段是数组添加一个值
        {"multi":true}
    )

    db.user.update(
        {"name":"yuanhao"},
        {"$push":{"hobbies":{"$each":["纹身","抽烟"]}}},#对某一个字段是数组添加多个值别忘了用$each
        {"multi":true}
    )

    #从头删-1,从尾删1
    db.user.update(
        {"name":"yuanhao"},
        {"$pop":{"hobbies":-1}},#从开始删除
        {"multi":true}
    )

    db.user.update(
        {"name":"yuanhao"},
        {"$pop":{"hobbies":1}},#从后面删除
        {"multi":true}
    )

    #按条件删
    db.user.update(
        {"name":"yuanhao"},
        {"$pull":{"hobbies":"纹身"}},#"$pull" 把符合条件的统统删掉,而$pop只能从两端删
        {"multi":true}
    )

    #3、$addToSet#添加数据,不重复添加
    db.t3.insert({"urls":[]})
    db.t3.update(
        {},
        {"$addToSet":{"urls":{"$each":[
            "http://www.baidu.com",
            "http://www.baidu.com",
            "http://www.baidu.com",
            "http://www.baidu.com",
            "http://www.baidu.com"
        ]}}},
        {"multi":true}
    )
View Code

2.删除方法

db.user.deleteOne({"_id":{"$gte":3}})#在这种方法可以删除查询到的一个
db.user.deleteMany({"_id":{"$gte":3}})#这种方法可以删除查询到的所有值
db.user.deleteMany({})#删除所有的的数据
View Code

3.聚合方法

一:$match
    例:
        select post from db1.emp where age > 20 group by post having avg(salary) > 10000;#把这个拆分3句话

    #$match#查询的条件的标志
    #1、select post from db1.emp where age > 20#sql
    db.emp.aggregate({"$match":{"age":{"$gt":20}}}) #aggregate是聚合的标志

    #$group#分组
    #2、select post from db1.emp where age > 20 group by post;
    db.emp.aggregate(
        {"$match":{"age":{"$gt":20}}},
        {"$group":{"_id":"$post"}}
    )

    #3、select post,avg(salary) as avg_salary from db1.emp where age > 20 group by post;
    db.emp.aggregate(
        {"$match":{"age":{"$gt":20}}},
        {"$group":{"_id":"$post","avg_salary":{"$avg":"$salary"}}}#这是显示的字段  #$salary是说明使用这个字段的值
    )

    #select post from db1.emp where age > 20 group by post having avg(salary) > 10000;
    db.emp.aggregate(
        {"$match":{"age":{"$gt":20}}},
        {"$group":{"_id":"$post","avg_salary":{"$avg":"$salary"}}},
        {"$match":{"avg_salary":{"$gt":10000}}}
    )

二:{"$project":{"要保留的字段名":1,"要去掉的字段名":0,"新增的字段名":"表达式"}}#映射是说明生成新的并展示新的表
    例1:
    db.emp.aggregate(
        {"$project":{"_id":0,"name":1,"post":1,"annual_salary":{"$multiply":[12,"$salary"]}}},
        {"$group":{"_id":"$post","平均年薪":{"$avg":"$annual_salary"}}},
        {"$match":{"平均年薪":{"$gt":1000000}}},
        {"$project":{"部门名":"$_id","平均年薪":1,"_id":0}}
    )

    例2:#$subtract是两个相减
    db.emp.aggregate(
        {"$project":{"_id":0,"name":1,"hire_period":{"$subtract":[new Date(),"$hire_date"]}}}
    )


    db.emp.aggregate(
        {"$project":{"_id":0,"name":1,"hire_year":{"$year":"$hire_date"}}}#取时间段的年
    )

    db.emp.aggregate(
        {"$project":{"_id":0,"name":1,"hire_period":{"$subtract":[{"$year":new Date()},{"$year":"$hire_date"}]}}}#工作了几年
    )

    例3:
    db.emp.aggregate(
        {"$project":{"_id":0,"new_name":{"$toUpper":"$name"},}}#名字变成大写
    )

    db.emp.aggregate(
        {"$match":{"name":{"$ne":"egon"}}},#ne是比较运算里的
        {"$project":{"_id":0,"new_name":{"$concat":["$name","_SB"]},}}
    )

    db.emp.aggregate(
        {"$match":{"name":{"$ne":"egon"}}},
        {"$project":{"_id":0,"new_name":{"$substr":["$name",0,3]},}}#$substr是截取某段
    )

三:{"$group":{"_id":分组字段,"新的字段名":聚合操作符}}

    #select post,max,min,sum,avg,count,group_concat from db1.emp group by post;

    db.emp.aggregate(
        {"$group":{
            "_id":"$post",
            "max_age":{"$max":"$age"},
            "min_id":{"$min":"$_id"},#$_id去找个字段的值
            "avg_salary":{"$avg":"$salary"},
            "sum_salary":{"$sum":"$salary"},
            "count":{"$sum":1},#获取个数的用法
            "names":{"$push":"$name"}
            }
        }
    )


四:排序:$sort、限制:$limit、跳过:$skip
    db.emp.aggregate(
        {"$match":{"name":{"$ne":"egon"}}},
        {"$project":{"_id":1,"new_name":{"$substr":["$name",0,3]},"age":1}},
        {"$sort":{"age":1,"_id":-1}},
        {"$skip":5},
        {"$limit":5}
    )


# 补充
db.emp.aggregate({"$sample":{"size":3}})#随机去三个数
View Code

4.使用pymongo模块连接数据库

from pymongo import MongoClient #pip3 install pymongo

client=MongoClient("mongodb://root:123@127.0.0.1:27017")#连接数据库

# db1=client.db1
db1=client['db1']
# print(db1.collection_names())

# table_emp=db1.emp
table_emp=db1['emp']
rows=table_emp.find({"_id":{"$gt":10}})

for row in rows:
    print(row)
View Code

爬虫提高方法的使用:

1.同步调用

import requests
#同步或者异步是指提交数据的方式
#同步是值原地等待提交任务返回结果
#异步是指一个任务提交完了,直接提交下一个任务。
def parse_page(res):
    print('PARSE %s' %(len(res)))

def get_page(url):
    print('GET %s' %url)
    response=requests.get(url)
    if response.status_code == 200:
        return response.text


if __name__ == '__main__':
    urls=[
        'https://www.baidu.com',
        'https://www.taobao.com',
        'https://www.openstack.org',
    ]
    for url in urls:
        res=get_page(url)
        parse_page(res)
View Code

2.多线程与多进程

import requests
from threading import Thread,current_thread

def parse_page(res):
    print('%s PARSE %s' %(current_thread().getName(),len(res)))

def get_page(url,callback=parse_page):
    print('%s GET %s' %(current_thread().getName(),url))
    response=requests.get(url)
    if response.status_code == 200:
        callback(response.text)


if __name__ == '__main__':
    urls=[
        'https://www.baidu.com',
        'https://www.taobao.com',
        'https://www.openstack.org',
    ]
    for url in urls:
        t=Thread(target=get_page,args=(url,))
        t.start()
View Code

3.线程池与进程池

import requests
from threading import current_thread#这个是打印出来现在是哪个线程。
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor

def parse_page(res):
    res=res.result()
    print('%s PARSE %s' %(current_thread().getName(),len(res)))

def get_page(url):
    print('%s GET %s' %(current_thread().getName(),url))
    response=requests.get(url)
    if response.status_code == 200:
        return response.text#返回的是字符串。

if __name__ == '__main__':
    urls=[
        'https://www.baidu.com',
        'https://www.taobao.com',
        'https://www.openstack.org',
    ]
    pool=ThreadPoolExecutor(50)#线程池

    for url in urls:
        pool.submit(get_page,url).add_done_callback(parse_page)

    pool.shutdown(wait=True)#这个是不在往里面放任务。
View Code

4.协程

from gevent import joinall,spawn,monkey;monkey.patch_all()#协程
import requests
from threading import current_thread

def parse_page(res):
    print('%s PARSE %s' %(current_thread().getName(),len(res)))

def get_page(url,callback=parse_page):
    print('%s GET %s' %(current_thread().getName(),url))
    response=requests.get(url)
    if response.status_code == 200:
        callback(response.text)

if __name__ == '__main__':
    urls=[
        'https://www.baidu.com',
        'https://www.taobao.com',
        'https://www.openstack.org',
    ]

    tasks=[]
    for url in urls:
        tasks.append(spawn(get_page,url))

    joinall(tasks)
View Code

5.使用asyncio

import requests
import asyncio
import uuid

User_Agent='Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'


def parse_page(res):
    with open('%s.html' %uuid.uuid1(),'wb') as f:
        f.write(res)

@asyncio.coroutine
def get_page(host,port=80,url='/',ssl=False,callback=parse_page):

    #1、建立连接
    if ssl:
        port=443
    print('下载:https:%s:%s:%s' %(host,port,url))
    recv,send=yield from asyncio.open_connection(host=host,port=port,ssl=ssl)

    #2、封装请求头
    request_headers="""GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: %s\r\n\r\n""" %(url,host,User_Agent)
    request_headers=request_headers.encode('utf-8')  # socket发送的是bytes类型转成字节形式

    #3、发送请求头

    send.write(request_headers)
    yield from send.drain()   #这是发送

    #4、接收响应头
    while True:
        line=yield from recv.readline()
        if line == b'\r\n':
            break
        print('%s 响应头: %s' %(host,line))

    #5、接收响应体
    text=yield from recv.read()
    # print(text)
    #6、执行回调函数完成解析
    callback(text)

    #7、关闭
    send.close()

if __name__ == '__main__':
    tasks=[
        get_page(host='www.baidu.com',url='/s?wd=美女',ssl=True),
        get_page(host='www.cnblogs.com',url='/linhaifeng/articles/7806303.html',ssl=True)
    ]


    loop=asyncio.get_event_loop()
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()
View Code

 

转载于:https://www.cnblogs.com/1a2a/p/8330590.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值