mongodb

mongo 客户端连接

db

  • db 显示当前正在使用的数据库
  • show dbs 显示所有数据
  • use db(name) 使用指定数据库
  • db.dropDatabase() 删除正在使用的数据库

collection

  • db.test 使用当前数据库下面的test集合进行操作,如果没有会自动创建
  • show collecitons 显示当前数据库下的所有集合
  • db.test.drop() 删除当前的集合

pymongo

pip install pymongo

入门使用

from pymongo import MongoClient

# 创建一个客户端链接服务器
client = MongoClient()
# 选择要操作数据的数据库和集合,返回一个可操作的集合对象
col = client['py']['test']

# 插入一条记录,需要传入一个字典即可
col.insert({"name": "py5"})
# 插入多条记录,需要传入一个列表,元素项为字典
col.insert([{"name": "小王", "age": 18}, {"name": "小红", "age": 20}])

在插入数据时,如果数据库和集合不存在,会自动创建

删除和更新

# 更新文档,1.条件 2,更新内容 3.multi参数表示是否更新多条数据,默认false
col.update({"age": 18}, {"$set": {"name": "小明"}}, multi=False)

# 删除文档,1.条件 2,multi参数表示是否删除多条满足的文档 默认True
col.remove({"age": 18}, multi=False)

查找

# # 遍历取出集合中的每条数据
ret = col.find()
for x in ret:
    print(x)
  • find()返回了存储结果集的游标,可以通过迭代的方式依次取出结果
比较运算符
stu = client['py']['stu']

insert_list = [{'name': '段誉', 'hometown': '⼤理', 'age': 16, 'gender': False},
               {'name': '洪七公', 'hometown': '华⼭', 'age': 18, 'gender': True},
               {'name': '⻩蓉', 'hometown': '桃花岛', 'age': 18, 'gender': False},
               {'name': '华筝', 'hometown': '蒙古', 'age': 18, 'gender': False},
               {'name': '郭靖', 'hometown': '蒙古', 'age': 20, 'gender': True},
               {'name': '⻩药师', 'hometown': '桃花岛', 'age': 40, 'gender': True},
               {'name': '段王爷', 'hometown': '⼤理', 'age': 45, 'gender': True}]
# 插入数据
stu.insert(insert_list)

# 查询age=20的记录
ret = stu.find({"age": 20})
# 查询所有 age <= 20的记录
ret = stu.find({"age": {"$lte": 20}})
# 查询所有 age > 20的记录
ret = stu.find({"age": {"$gt": 20}})
逻辑运算符
# 逻辑预算符,and关系
ret = stu.find({"age": 18, "gender": False})
# 逻辑预算符,or关系
ret = stu.find({"$or": [{"age": 18}, {"gender": False}]})
ret = stu.find({"$or": [{"age": {"$gte": 18}}, {"gender": False}]})
范围运算符
# 范围运算符 in
# ret = stu.find({"age": {"$in": [18, 20]}})
翻页
# 翻页 skip 跳过  limit 选中
ret = stu.find()
for x in ret:
    print(x)

print("*" * 100)

ret = stu.find().skip(3).limit(2)
for x in ret:
    print(x)
投影
# 投影,约束需要显示的字段
# ret = stu.find({}, {"_id": 0, "name": 1, "hometown": 1})
排序
# 排序 1升序,-1降序
import pymongo
ret = stu.find().sort([("age", pymongo.ASCENDING), ("gender", pymongo.DESCENDING)])
统计个数
# 统计个数 count中只能计数
ret = stu.find({"age": {"$lt": 18}}).count()
print(ret)
去重
# 筛选数据并去重,返回的是一个去重后的列表
ret = stu.distinct("hometown", {"age": {"$gt": 20}})
for x in ret:
   print(x)

管道

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

管道命令
  • $group: 将集合中的⽂档分组, 可⽤于统计结果
  • $match: 过滤数据, 只输出符合条件的⽂档
  • $project: 修改输⼊⽂档的结构, 如重命名、 增加、 删除字段、 创建计算结果
  • $sort: 将输⼊⽂档排序后输出
  • $limit: 限制聚合管道返回的⽂档数
  • $skip: 跳过指定数量的⽂档, 并返回余下的⽂档
管道表达式
  • $sum: 计算总和, $sum:1 表示以⼀倍计数
  • $avg: 计算平均值
  • $min: 获取最⼩值
  • $max: 获取最⼤值
  • $push: 在结果⽂档中插⼊值到⼀个数组中

语法:db.集合名称.aggregate({管道:{表达式}})

# $group分组  "_id"分组的依据   $sum:1统计组内个数, $sum:$age 组内的年龄求和  $push 数据透视,组内元素放入一个列表中
ret = stu.aggregate(
     [{"$group": {"_id": "$hometown", "count": {"$sum": 1}, "age": {"$sum": "$age"}, "name": {"$push": "$name"}}}])

# 多个字段进行分组
ret = stu.aggregate([{"$group": {"_id": {"性别": "$gender", "姓名": "$name"}}}])

ret = stu.aggregate([
    {"$match": {"age": {"$gt": 20}}},
    {"$group": {"_id": {"gender": "$gender", "hometown": "$hometown"}}},
    {"$project": {"_id": 0, "性别": "$_id.gender", "故乡": "$_id.hometown"}},
    {"$group": {"_id": "$性别", "人数": {"$sum": 1}}}])

ret = stu.aggregate([{"$group": {"_id": "$hometown", "count": {"$sum": 1}}},
                     {"$sort": {"count": pymongo.ASCENDING}},
                      {"$skip": 1},
                     {"$limit": 2}])

索引

索引的作用?

  • 加快查询速度
  • 进行数据的去重
# 设置索引,1.提升查找效率,2数据去重
stu.ensure_index([("name", pymongo.ASCENDING)], unique=True)
# 获取索引,并美化打印
x = stu.index_information()
print(json.dumps(x, indent=2))

# 设置复合索引实现数据去重
stu.ensure_index([("name", pymongo.ASCENDING), ("age", pymongo.DESCENDING)])

爬虫中,数据去重的一个重要手段就是:选择合适数据字段,建立复合索引