MongoDB-CURD增、删、改、查

MongoDB

  • MongoDB操作
    • 创建数据库
    • 添加数据
      • 插入多条
      • 自定义_id插入
    • 查询
      • 查询指定字段
      • 指定条件查询
      • type类型查询
      • 正则表达式查询
      • 指定查询返回数
    • 修改文档
    • 删除数据

MongoDB操作

在 Python 中, 如果想要和 MongoDB 进行交互 ,就需要借助于 PyMongo 库:pip install pymongo
使用python 进行简单的插入和查询。

# -*- coding: utf-8 -*-
# @Date    : 2018-11-13 16:37:59
# @Author  : Your Name ([email protected])
# @Link    : http://example.org
from pymongo import MongoClient
client = MongoClient('localhost', 27017)
# client = MongoClient('mongodb://localhost:27017/')

db = client.test
# db = client['test']

collection = db.students

# collection = db['students']

student1 = {
    'id': '20170101',
    'name': 'Jordan',
    'age': 22,
    'gender': 'male'
}

student2 = {
    'id': '20170202',
    'name': 'Mike',
    'age': 21,
    'gender': 'male'
}

# result = collection.insert(student1)
result = collection.insert_many([student1, student2])
print(result)

results = collection.find({'age': 20})
print(results)
for result in results:
    print(result)

简单的插入和查询。结果:

5bea8f3f8c70ac282070ff43

{'_id': ObjectId('5bea8e728c70ac26b5a547dd'), 'id': '20170101', 'name': 'Jordan', 'age': 20, 'gender': 'male'}
[Finished in 0.6s]

创建数据库

MongoDB 中默认的数据库为 test,如果你没有创建新的数据库,集合将存放在 test 数据库中。在 MongoDB 中,集合只有在内容插入后才会创建! 就是说,创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建。

import pymongo
client = pymongo.MongoClient(host='localhost', port=27017)
# 创建数据库 只有在内容插入后才会创建
db = client['first_demo']

# 返回当前数据库列表
dblist = client.list_database_names()
print(dblist)
if 'first_demo' in dblist:
    print('数据库已存在')

# 创建集合 集合只有在内容插入后才会创建
col = db['sites']

# 返回数据库内集合
collist = db.list_collection_names()
if 'sites' in collist:
    print('集合已存在')

添加数据

文档的数据结构和JSON基本一样。
所有存储在集合中的数据都是BSON格式。
BSON是一种类json的一种二进制形式的存储格式,简称Binary JSON。
集合中插入文档使用insert_one()方法,第一参数是字典 name => value 对, 集合中插入多个文档使用 insert_many() 方法,该方法的第一参数是字典列表

db = client['first_demo']
col = db['sites']
# 集合内插入
d1 = {'name': 'google', 'id': 2, 'url': 'https://www.google.com'}
x = col.insert_one(d1)
# 方法返回 InsertOneResult 对象,该对象包含 inserted_id 属性,它是插入文档的 id 值
print(x)  # 
print(x.inserted_id)  # 5c00af888c70ac6346a4ab25

插入多条

insert_many()插入多条文档:

# 插入多条数据
mylist = [
    {"name": "Taobao", "alexa": "100", "url": "https://www.taobao.com"},
    {"name": "QQ", "alexa": "101", "url": "https://www.qq.com"},
    {"name": "Facebook", "alexa": "10", "url": "https://www.facebook.com"},
    {"name": "知乎", "alexa": "103", "url": "https://www.zhihu.com"},
    {"name": "Github", "alexa": "109", "url": "https://www.github.com"},
]
x = col.insert_many(mylist)
# 输出插入的所有文档对应的 _id 值
print(x.inserted_ids)

所有文档的id:

[ObjectId('5c00b2068c70ac67e3a197fe'), ObjectId('5c00b2068c70ac67e3a197ff'), 
ObjectId('5c00b2068c70ac67e3a19800'), ObjectId('5c00b2068c70ac67e3a19801'), 
ObjectId('5c00b2068c70ac67e3a19802')]

自定义_id插入

也可以自己指定'_id'进行插入:

mylist_2 = [
    {'_id': 1, 'name': 'Jack', 'num': 1233},
    {'_id': 2, 'name': 'Tom', 'num': 1233},
    {'_id': 3, 'name': 'Candy', 'num': 1233},
    {'_id': 4, 'name': 'Ana', 'num': 1233},
]
x = col.insert_many(mylist_2)
print(x.inserted_ids)
# [1, 2, 3, 4]

查询

使用find(self, *args, **kwargs)进行查询,类似 SQL 中的 SELECT * 操作:

db = client['first_demo']
col = db['sites']
for x in col.find():
    print(x)

查询到’sites’内的所有文档:

{'_id': ObjectId('5c00ad0c8c70ac5e7746832d'), 'name': 'google', 'id': 1, 'url': 'https://www.google.com'}
{'_id': ObjectId('5c00ad1b8c70ac5e8b08ce09'), 'name': 'google', 'id': 1, 'url': 'https://www.google.com'}
{'_id': ObjectId('5c00af888c70ac6346a4ab25'), 'name': 'google', 'id': 2, 'url': 'https://www.google.com'}
...
{'_id': 1, 'name': 'Jack', 'num': 1233}
{'_id': 2, 'name': 'Tom', 'num': 1233}
{'_id': 3, 'name': 'Candy', 'num': 1233}
{'_id': 4, 'name': 'Ana', 'num': 1233}

查询指定字段

使用find查询指定字段的数据,将要返回的字段对应值设置为1

for x in col.find({}, {"_id": 0, 'name': 1, 'url': 1}):
    print(x)
{'name': 'google', 'url': 'https://www.google.com'}
{'name': 'Taobao', 'url': 'https://www.taobao.com'}
{'name': 'QQ', 'url': 'https://www.qq.com'}
{'name': 'Facebook', 'url': 'https://www.facebook.com'}
{'name': '知乎', 'url': 'https://www.zhihu.com'}
...
{'name': 'Jack'}
{'name': 'Tom'}
{'name': 'Candy'}
{'name': 'Ana'}

除了_id 不能在一个对象中同时指定 0 和 1,如果设置了一个字段为 0,则其他都为 1,反之亦然。

指定条件查询

在 find() 中设置参数来过滤数据, 类似sql的where:

操作 格式 RDBMS中的类似语句
等于 {key:value} where by = ‘菜鸟教程’
小于 {key:{$lt:value}} where xxx < 50
小于或等于 {key:{$lte:value}} where xxx <= 50
大于 {key:{$gt:value}} where xxx > 50
大于或等于 {key:{$gte:value}} where xxx >= 50
不等于 {key:{$ne:value}} where xxx != 50
AND {key1:value1, key2:value2} where xxx= and yyy=
OR {"$or":[{key1:value1}, {key2:value2}] } where xxx= or yyy=

AND条件:

# 指定条件查询 类似 sql where name = googel and id =1
query_1 = {'name': 'google', 'id': 1}
doc_1 = col.find(query_1)
for x in doc_1:
     print(x)
# {'_id': ObjectId('5c00ad0c8c70ac5e7746832d'), 'name': 'google', 'id': 1, 'url': 'https://www.google.com'}
# {'_id': ObjectId('5c00ad1b8c70ac5e8b08ce09'), 'name': 'google', 'id': 1, 'url': 'https://www.google.com'} 

OR条件:

# or  where name = Jack or _id = 2
query_2 = {"$or": [{'name': 'Jack'}, {'_id': 2}]}
doc_2 = col.find(query_2)
for x in doc_2:
    print(x)
# {'_id': 1, 'name': 'Jack', 'num': 1233}
# {'_id': 2, 'name': 'Tom', 'num': 1233}

大于:

# 大于 where _id > 2
query_3 = {'_id': {'$gt': 2}}
doc_3 = col.find(query_3)
for x in doc_3:
    print(x)
# {'_id': 3, 'name': 'Candy', 'num': 1233}
# {'_id': 4, 'name': 'Ana', 'num': 1233}

条件联用:

# where name='QQ' or (id > 1 and name = 'google')
query_4 = {'$or': [{"name": "QQ"}, {"id": {"$gt": 1}, "name": "google"}]}
doc_4 = col.find(query_4)
for x in doc_4:
    print(x)
# {'_id': ObjectId('5c00af888c70ac6346a4ab25'), 'name': 'google', 'id': 2, 'url': 'https://www.google.com'}
# {'_id': ObjectId('5c00b2068c70ac67e3a197fd'), 'name': 'google', 'id': 2, 'url': 'https://www.google.com'}
# {'_id': ObjectId('5c00b2068c70ac67e3a197ff'), 'name': 'QQ', 'alexa': '101', 'url': 'https://www.qq.com'}
# {'_id': ObjectId('5c01d7ed8c70ac1f294fb30a'), 'name': 'google', 'id': 2, 'url': 'https://www.google.com'}
# {'_id': ObjectId('5c01d7ed8c70ac1f294fb30c'), 'name': 'QQ', 'alexa': '101', 'url': 'https://www.qq.com'}

type类型查询

$type操作符是基于BSON类型来检索集合中匹配的数据类型,并返回结果,MongoDB支持的数据类型有double, string, JavaScript和Timestamp等, 具体查看: https://docs.mongodb.com/manual/reference/bson-types/

col_2 = db['student']
stu_list = [
    {'_id': 1, 'name': 'Jack', 'socre': 90},
    {'_id': 2, 'name': 'Tom', 'socre': 85},
    {'_id': 3, 'name': 'Candy', 'socre': "A"},
    {'_id': 4, 'name': 'Ana', 'socre': "B"},
]
# col_2.insert_many(stu_list)
for x in col_2.find():
    print(x)
print('-----')
query_5 = {'socre': {"$type": "string"}}
doc_5 = col_2.find(query_5)
for x in doc_5:
    print(x)
# -------------
# {'_id': 1, 'name': 'Jack', 'socre': 90}
# {'_id': 2, 'name': 'Tom', 'socre': 85}
# {'_id': 3, 'name': 'Candy', 'socre': 'A'}
# {'_id': 4, 'name': 'Ana', 'socre': 'B'}
# -----
# {'_id': 3, 'name': 'Candy', 'socre': 'A'}
# {'_id': 4, 'name': 'Ana', 'socre': 'B'}

正则表达式查询

还可以使用正则表达式作为修饰符,正则表达式修饰符只用于搜索字符串的字段,类比SQL中的REGEX, 使用$regex关键字:

# 正则表达式 查询 只能用于字符串
query_6 = {"name": {"$regex": "^g\w+e$"}}
doc_6 = col.find(filter=query_6, projection={"_id": 0, 'url': 0})
for x in doc_6:
    print(x)
# {'name': 'google', 'id': 1}
# {'name': 'google', 'id': 1}
# {'name': 'google', 'id': 2}
# {'name': 'google', 'id': 2}
# {'name': 'google', 'id': 2}

指定查询返回数

使用limit参数,或在查询后使用limit()函数,可以限定条数:

# 指定查询返回条数
# doc_7 = col.find(filter={'name': "google"}, projection={"url": 0}, limit=3)
doc_7 = col.find(filter={'name': "google"}, projection={"url": 0}).limit(3)
for x in doc_7:
    print(x)
# {'_id': ObjectId('5c00ad0c8c70ac5e7746832d'), 'name': 'google', 'id': 1}
# {'_id': ObjectId('5c00ad1b8c70ac5e8b08ce09'), 'name': 'google', 'id': 1}
# {'_id': ObjectId('5c00af888c70ac6346a4ab25'), 'name': 'google', 'id': 2}

修改文档

update_one()方法修改文档中的记录。该方法第一个参数为查询的条件,第二个参数为要修改的字段。如果查找到的匹配数据多余一条,则只会修改第一条。
update_one(self, filter, update, upsert=False,bypass_document_validation=False,
collation=None, array_filters=None, session=None)

for x in col.find():
    print(x)
# {'_id': 1, 'name': 'Jack', 'socre': 90}
# {'_id': 2, 'name': 'Tom', 'socre': 85}
# {'_id': 3, 'name': 'Candy', 'socre': 'A+'}
# {'_id': 4, 'name': 'Ana', 'socre': 'B'}
#
result = col.update_one(filter={'socre': {"$type": 'string'}},
                        update={'$set': {"socre": "S+"}})
print(result.matched_count)
print(result.modified_count)
# 1
# 1
# 
for x in col.find():
    print(x)
# {'_id': 1, 'name': 'Jack', 'socre': 90}
# {'_id': 2, 'name': 'Tom', 'socre': 85}
# {'_id': 3, 'name': 'Candy', 'socre': 'S+'}
# {'_id': 4, 'name': 'Ana', 'socre': 'B'}

update_one方法只能修匹配到的第一条记录,如果要修改所有匹配到的记录,可以使用 update_many()

for x in col.find():
    print(x)
# {'_id': 1, 'name': 'Jack', 'socre': 90}
# {'_id': 2, 'name': 'Tom', 'socre': 85}
# {'_id': 3, 'name': 'Candy', 'socre': 'S+'}
# {'_id': 4, 'name': 'Ana', 'socre': 'B'}

result = col.update_many(filter={'score': {'$type': "int"}},
                         update={"$inc": {'score': 1}})
print(result.matched_count)
print(result.modified_count)
# 2
# 2
for x in col.find():
    print(x)
# {'_id': 1, 'name': 'Jack', 'score': 91}
# {'_id': 2, 'name': 'Tom', 'score': 86}
# {'_id': 3, 'name': 'Candy', 'score': 'S+'}
# {'_id': 4, 'name': 'Ana', 'score': 'B'}

replace_one 可以替换当前满足条件的一个文档:

for x in col.find():
    print(x)
# {'_id': 1, 'name': 'Jack', 'score': 92}
# {'_id': 2, 'name': 'Tom', 'score': 87}
# {'_id': 3, 'name': 'Candy', 'score': 'S+'}
# {'_id': 4, 'name': 'Ana', 'score': 'B'}

ret = col.replace_one({'name': 'Jack'}, {'name': 'John'})
print(ret.matched_count)
print(ret.modified_count)
# 1
# 1
for doc in col.find():
    print(doc)
# {'_id': 1, 'name': 'John'}
# {'_id': 2, 'name': 'Tom', 'score': 87}
# {'_id': 3, 'name': 'Candy', 'score': 'S+'}
# {'_id': 4, 'name': 'Ana', 'score': 'B'}

其他:

  • find_one_and_update:查找单个文档并修改,返回值可选择为修改之前的文档或修改之后的文档;
  • find_one_and_replace:查找单个文档并替换,返回值可选择为替换之前的文档或替换后的新文档;

删除数据

使用delete_one方法来删除一个文档,该方法第一个参数为查询对象,指定要删除哪些数据

for doc in col.find():
    print(doc)
# {'_id': 1, 'name': 'John'}
# {'_id': 2, 'name': 'Tom', 'score': 87}
# {'_id': 3, 'name': 'Candy', 'score': 'S+'}
# {'_id': 4, 'name': 'Ana', 'score': 'B'}
print('--------')
col.delete_one({'name': 'Ana'})
for doc in col.find():
    print(doc)
# {'_id': 1, 'name': 'John'}
# {'_id': 2, 'name': 'Tom', 'score': 87}
# {'_id': 3, 'name': 'Candy', 'score': 'S+'}

delete_many可以删除多个文档:

query = {'$or': [{'_id': 2}, {'_id': 3}]}
ret = col.delete_many(query)
print(ret.deleted_count)
# 2
for doc in col.find():
    print(doc)
# {'_id': 1, 'name': 'John'}

find_one_and_delete:寻找并删除单个文档,返回这个文档的值:

query = {'name': 'John'}
ret = col.find_one_and_delete({'name': 'John'})
print(ret)
# {'_id': 1, 'name': 'John'}
print(col.count_documents(query))
# 0

可以使用 drop() 方法来删除一个集合

db = client['first_demo']
col = db['student']
col.drop()

可以在终端进入数据库查询

> use first_demo
switched to db first_demo
> show tables
sites

你可能感兴趣的:(学习笔记)