菜单

MongoDB


发布于 2024-10-28 / 6 阅读 / 0 评论 /
import pymongo 连接 1️⃣ 标准URL语法 mongodb://username:password@host:port/defaultauthdb 2️⃣ Pyth

import pymongo

连接

1️⃣ 标准URL语法

mongodb://username:password@host:port/defaultauthdb

2️⃣ Python语句

#连接mongodb
myclient = pymongo.MongoClient("mongodb://ecnu10225501432:ECNU10225501432@172.16.208.86:27017/admin")

逻辑结构

  • client:连接

  • client.database/client['database']:数据库(database表示数据库名)

  • database.set/database['set']:集合(set表示集合名)

  • set.{anyCommand}{anyCommand}表示操作语句,返回集合内文档

MySQL 术语

MongoDB 术语

解释

Database(数据库)

Database(数据库)

两者中都使用相同术语,表示数据库的集合。

Table(表)

Collection(集合)

在MySQL中称为表,在MongoDB中称为集合,存储数据记录的容器。

Row(行)

Document(文档)

在MySQL中每行代表一条记录,而在MongoDB中每个文档是类似的概念,包含数据的键值对。

Column(列)

Field(字段)

MySQL的列对应MongoDB的字段,字段表示文档中键值对的键。

Primary Key(主键)

_id(唯一标识符)

MySQL中的主键在MongoDB中对应每个文档的_id字段,默认由MongoDB生成唯一ID。

Index(索引)

Index(索引)

两者都用索引来加速查询,但MongoDB的索引可以是嵌套的字段或数组。

Schema(模式)

Schema-less(无模式)

MySQL有固定模式,MongoDB是无模式的,即文档的结构不必一致。

JOIN(连接)

Embedded Documents(嵌入文档) 或 $lookup

MongoDB没有直接的JOIN,但可以通过嵌入文档或$lookup操作实现类似的功能。

SQL(查询语言)

MongoDB Query(MongoDB查询)或 Aggregation Pipeline(聚合管道)

MySQL使用SQL语言,MongoDB有自己的查询语法和聚合框架。

Transaction(事务)

Transaction(事务)

MongoDB 4.0+版本支持多文档ACID事务,类似MySQL的事务。

Foreign Key(外键)

Reference(引用)

MongoDB没有明确的外键概念,但可以通过引用文档的方式实现类似的功能。

View(视图)

View(视图)

MongoDB 3.4+版本支持视图,与MySQL的视图类似。

操作符

MongoDB 支持多种操作符,主要分为比较操作符逻辑操作符元素操作符数组操作符等类别。以下是一个表格,列出了 MongoDB 中常用的操作符,方便参考。

操作符类别

操作符

说明

比较操作符

$eq

等于(等价于 SQL 中的 =

$ne

不等于

$gt

大于

$gte

大于等于

$lt

小于

$lte

小于等于

$in

在指定数组范围内

$nin

不在指定数组范围内

逻辑操作符

$and

逻辑与(多个条件都满足)

$or

逻辑或(任一条件满足)

$not

取反(条件不满足)

$nor

逻辑非(多个条件都不满足)

元素操作符

$exists

判断字段是否存在

$type

匹配字段的类型

数组操作符

$all

数组字段必须包含指定的所有元素

$elemMatch

匹配满足指定条件的数组元素

$size

匹配数组字段的长度

评估操作符

$mod

模运算(取余)

$regex

正则表达式匹配

$text

文本搜索

$where

使用 JavaScript 表达式进行匹配

聚合操作符

$sum

计算总和

$avg

计算平均值

$min

计算最小值

$max

计算最大值

更新操作符

$set

设置字段的值

$unset

删除字段

$inc

对字段值进行递增

$push

向数组字段追加值

$pop

从数组字段中删除第一个或最后一个元素

$pull

从数组中删除匹配条件的所有元素

位操作符

$bitsAllSet

匹配所有设置位

$bitsAnySet

匹配任意设置位

$bitsAllClear

匹配所有清除位

$bitsAnyClear

匹配任意清除位

这是 MongoDB 的常见操作符,涵盖了基本查询、逻辑操作、数组操作等。你可以根据需要组合使用这些操作符,完成各种复杂的查询或更新操作。

CRUD

1️⃣ Create

mongodb_client = pymongo.MongoClient("mongodb://username:password@host:port/defaultauthdb")
mongodb_database = mongodb_client['yourdatabase'] # 另一写法mongodb_database = mongodb_client.yourdatabase
mongodb_collection = mongodb_database['yourset'] # 另一写法mongodb_database = mongodb_database.yourset
​
# Python数据类型中的字典
python_dict = {key1 : value1, key2 : value2 }
python_dict_list = [python_dict,python_dict,python_dict,....] 
​
# Create语句
​
# 插入一个文档
# 接收的参数是python集字典
# InsertOneResult 对象,该对象包含 inserted_id 属性,它是插入文档的 id 值
mongodb_collection.insert_one(python_dict)
​
# 插入多个文档
# 接收的参数是元素为python字典的python列表(字典列表)
# 返回 InsertManyResult 对象,该对象包含 inserted_ids 属性,该属性保存着所有插入文档的 id 值
mongodb_collection.insert_many(python_dict_list)

2️⃣ Read(Find)

mongodb_client = pymongo.MongoClient("mongodb://username:password@host:port/defaultauthdb")
mongodb_database = mongodb_client['yourdatabase'] # 另一写法mongodb_database = mongodb_client.yourdatabase
mongodb_collection = mongodb_database['yourset'] # 另一写法mongodb_database = mongodb_database.yourset
​
# Python数据类型中的字典
python_search_dict = {key1 : value1, key2 : value2 }
python_return_dict = {key1 : value1, key2 : value2 }
​
# 查询符合python_search_dict字段的文档,并按python_return_dict要求返回第一个文档(不一定为_id最小的)
# python_search_dict
mongodb_collection.findone(python_search_dict, python_return_dict)
​
​
# 查询符合python_search_dict字段的文档,并按python_return_dict要求返回所有匹配文档
# 返回可迭代Pymongo对象,可被for循环展开,展开的每一条都是对应python_return_dict输出要求的python字典
mongodb_collection.find(python_search_dict, python_return_dict)
​

🥇 python_search_dict

或 且

# 默认情况下,自动意味着并列关系,即查询同时包含'key1':'value1','key2':'value2'的文档
python_search_dict = {
    'key1':'value1',
    'key2':'value2'
}
​
# 想要表达 或 关系的话,需要使用 $or 操作符
# '$or' 为键,其值声明了一个字典列表,列表内包含想要并列关系的python字典
# '$and' 操作符同理
# 在字典列表里,可以继续嵌套$or &and操作符,在字典列表里的一个字典内,键值对改成$or $and 需要的格式
python_search_dict = {
    'key1':'value1',
    '$or': [
        {'favorites.books': '谁动了我的奶酪'},
        {'$and': [
            {'age': {'$gte': 25}},
            {'address.aName': {'$ne': '纽约'}}
        ]}
    ]
}

逻辑

符号

含义

示例

$lt

小于

{'age': {'$lt': 20}}

$gt

大于

{'age': {'$gt': 20}}

$lte

小于等于

{'age': {'$lte': 20}}

$gte

大于等于

{'age': {'$gte': 20}}

$ne

不等于

{'age': {'$ne': 20}}

$in

在范围内

{'age': {'$in': [20, 23]}}

$nin

不在范围内

{'age': {'$nin': [20, 23]}}

在需要使用的键值对处,将对应值改为如上表所示的一个新字典,新字典键为操作符,值为你需要的数字

匹配

符号

含义

示例

示例含义

$regex

匹配正则表达式

{'name': {'$regex': '^M.*'}}

name以M开头

$exists

属性是否存在

{'name': {'$exists': True}}

name属性存在

$type

类型判断

{'age': {'$type': 'int'}}

age的类型为int

$mod

数字模操作

{'age': {'$mod': [5, 0]}}

年龄模5余0

$text

文本查询

{'$text': {'$search': 'Mike'}}

text类型的属性中包含Mike字符串

$where

高级条件查询

{'$where': 'obj.fans_count == obj.follows_count'}

自身粉丝数等于关注数

🥈 python_return_dict

# _id是一个特殊字段,只有指定`_id:0`才不会返回,否则默认返回
# 除'_id'外,不能同时存在 包含字段 和 排除字段
​
# 包含字段
# 以下效果为返回name字段
# 同时_id字符也会默认返回
python_return_dict = {
    'name': 1
}
​
# 排除字段
# 以下效果为返回除了name字段以外的所有字段
# 同时_id字符也会默认返回
python_return_dict = {
    'name': 0
}
​
# 排除_id字段
# 这是合法的,因为_id是特殊字段,默认返回,除非显式声明不返回
python_return_dict = {
    '_id': 0
    'name': 1
}

🥉 排序 偏移 去重

排序

# 列名,即字段的键名
# pymongo.ASCENDING指定升序(或者1);  
# pymongo.DESCENDING指定降序(或者-1);
​
mongodb_collection.find().sort('列名', 升降序标志 )
​
# 返回值为python字典列表
results = mongodb_collection.find().sort('name', pymongo.ASCENDING)
print([result['name'] for result in results])

偏移

# skip(n):跳过前 n 条记录。例如,skip(2) 会跳过查询结果的前两条记录,从第三条记录开始返回
results = mongodb_collection.find().sort('name', pymongo.ASCENDING).skip(2)
print([result['name'] for result in results])
​
# limit(m):限制返回的记录数为 m 条。例如,limit(2) 会返回最多两条记录。
results = mongodb_collection.find().sort('name', pymongo.ASCENDING).skip(2).limit(2)
print([result['name'] for result in results])

去重

# field:你想要提取的字段(这里是 'name')。
# query(可选):可以用来过滤符合条件的文档(如果不提供,则提取集合中的所有文档)。等价于python_search_dict
mongodb_collection.distinct(field, query)
[
    { "_id": 1, "name": "Alice", "age": 25 },
    { "_id": 2, "name": "Bob", "age": 30 },
    { "_id": 3, "name": "Alice", "age": 29 },
    { "_id": 4, "name": "Charlie", "age": 35 },
    { "_id": 5, "name": "Bob", "age": 28 }
]
users_col.distinct('name')
["Alice", "Bob", "Charlie"]


users_col.distinct('name', { "age": { "$gt": 28 } })
["Bob", "Charlie"]

3️⃣ Update

mongodb_client = pymongo.MongoClient("mongodb://username:password@host:port/defaultauthdb")
mongodb_database = mongodb_client['yourdatabase'] # 另一写法mongodb_database = mongodb_client.yourdatabase
mongodb_collection = mongodb_database['yourset'] # 另一写法mongodb_database = mongodb_database.yourset

# Python数据类型中的字典
python_search_dict = {key1 : value1, key2 : value2 }
python_toupdate_dict = {key1 : value1, key2 : value2 }

# 更新一条信息
# python_search_dict格式参考上方
# python_toupdate_dict填写需要更新的键值对
collection.update_one(python_search_dict, python_toupdate_dict)

# 更新所有符合条件的文档字段
collection.update_many(python_search_dict, python_toupdate_dict)

🥇 python_toupdate_dict

# python_toupdate_dict为一个python字典
# 键为更新操作符
# 值为一个字典,字典内包含需要更新的键,进行更新操作设定的值
python_toupdate_dict = {
	'$set':{'height': 1.81}, # 设置身高为1.81
	'$inc': {'age': 1}  # 年龄增加一岁
}

4️⃣ Delete

# 删除一条符合要求的记录
mongodb_collection.delete_one(python_search_dict)

# 删除所有符合要求的记录记录
mongodb_collection.delete_many(python_search_dict)

##

Lab2 实验代码

练习1:

将下面一位用户的信息插入users表中:

{
    "name" : "juyi",
    "country" : "China",
    "address" : {
        "aCode" : "002",
        "aName" : "广州"},
    "favorites" : {
        "movies" : [ 
            "肖生克的救赎", 
            "阿甘正传", 
            "头号玩家"],
        "cites" : [ 
            "衡阳", 
            "南宁", 
            "上海", 
            "深圳"]},
    "age" : 25,
    "height" : 1.69
}

解答

user2 = {
    "name" : "juyi",
    "country" : "China",
    "address" : {
        "aCode" : "002",
        "aName" : "广州"},
    "favorites" : {
        "movies" : [ 
            "肖生克的救赎", 
            "阿甘正传", 
            "头号玩家"],
        "cites" : [ 
            "衡阳", 
            "南宁", 
            "上海", 
            "深圳"]},
    "age" : 25,
    "height" : 1.69
}

result = users_col.insert_one(user2)

练习2:

插入下面多位user的信息(要求使用insert_many):

user6 = {
    "name" : "xiaoxiaobu",
    "country" : "USA",
    "address" : {
        "aCode" : "001",
        "aName" : "纽约"},
    "favorites" : {
        "books" : [ 
            "权利的游戏", 
            "教父"],
        "cites" : [ 
            "芝加哥", 
            "芝加哥", 
            "洛杉矶"]},
    "age" : 26,
    "height" : 1.78
}

user7 = {
    "name" : "lisa",
    "country" : "USA",
    "address" : {
        "aCode" : "001",
        "aName" : "纽约"},
    "favorites" : {
        "books" : [ 
            "权利的游戏", 
            "飘", 
            "谁动了我的奶酪"],
        "cites" : [ 
            "芝加哥", 
            "芝加哥", 
            "洛杉矶"]},
    "age" : 20,
    "height" : 1.71
}

user8 = {
    "name" : "xiaoxiao",
    "country" : "USA",
    "address" : {
        "aCode" : "005",
        "aName" : "费城"},
    "favorites" : {
        "books" : [ 
            "权利的游戏", 
            "飘"],
        "cites" : [ 
            "芝加哥", 
            "芝加哥", 
            "洛杉矶"]},
    "age" : 21,
    "height" : 1.75
}

解答

more_users2 = [

{
    "name" : "xiaoxiaobu",
    "country" : "USA",
    "address" : {
        "aCode" : "001",
        "aName" : "纽约"},
    "favorites" : {
        "books" : [ 
            "权利的游戏", 
            "教父"],
        "cites" : [ 
            "芝加哥", 
            "芝加哥", 
            "洛杉矶"]},
    "age" : 26,
    "height" : 1.78
},

{
    "name" : "lisa",
    "country" : "USA",
    "address" : {
        "aCode" : "001",
        "aName" : "纽约"},
    "favorites" : {
        "books" : [ 
            "权利的游戏", 
            "飘", 
            "谁动了我的奶酪"],
        "cites" : [ 
            "芝加哥", 
            "芝加哥", 
            "洛杉矶"]},
    "age" : 20,
    "height" : 1.71
},

{
    "name" : "xiaoxiao",
    "country" : "USA",
    "address" : {
        "aCode" : "005",
        "aName" : "费城"},
    "favorites" : {
        "books" : [ 
            "权利的游戏", 
            "飘"],
        "cites" : [ 
            "芝加哥", 
            "芝加哥", 
            "洛杉矶"]},
    "age" : 21,
    "height" : 1.75
}



]


users_col.insert_many(more_users2)
content = users_col.find()
for each in content:
    print(each)

练习3:

查询country为China的用户(要求:输出为列表)

解答

content = [x for x in users_col.find({'country': 'China'}, {'_id': 0})]
print(content)

练习4:

查询所有age > 25的记录,并且不显示_id

解答

results = users_col.find({'age': {'$gt': 25 }},{'_id':0})
for each in results:
    print(each)

练习5:

查询用户的country是USA并且年龄大于20岁的数据。

解答

results = users_col.find({'$and': [{'country': 'USA'}, {'age': {'$gt': 20}}]}, {'_id': 0})
for each in results:
    print(each)

练习6:

查找喜欢书籍的,且身高在1.68-1.72m之间的中国用户

解答

results = users_col.find({
    'country': 'China',
    'favorites.books': {'$exists': True, '$ne': []},
    'height': {'$gte': 1.68, '$lte': 1.72}
}, {'_id': 0})

for each in results:
    print(each)

练习7:

查找喜欢书籍“谁动了我的奶酪” 或者 年龄不小于25岁且家不在纽约的美国用户

解答

results = users_col.find({
    'country': 'USA',
    '$or': [
        {'favorites.books': '谁动了我的奶酪'},
        {'$and': [
            {'age': {'$gte': 25}},
            {'address.aName': {'$ne': '纽约'}}
        ]}
    ]
}, {'_id': 0})

for each in results:
    print(each)

练习8:

查找既喜欢cites也喜欢books,且身高在1.80以上的用户

解答

results = users_col.find({
    'favorites.books': {'$exists': True},
    'favorites.cites': {'$exists': True},
    'height': {'$gt': 1.79}
}, {'_id': 0})

for each in results:
    print(each)

练习9:

查找名字以xiao开头,且年龄在20-25岁之间的用户

解答

results = users_col.find({
    'name': {'$regex': '^xiao.*'},
    'age': {'$gte': 20, '$lte': 25}
},{'_id':0}
)
for each in results:
    print(each)

练习10:

查找用户中身高按降序排序中,排名4-6的用户

解答

results = users_col.find({}, {'_id': 0}).sort('height', -1).skip(3).limit(3)
print([result for result in results])

练习11:

将喜欢书籍且在中国的用户,所在城市改为上海

解答

condition = {
    'favorites.books': {'$exists': True},
    'country': 'China'
}
result = users_col.update_many(condition, {'$set': {'address.aCode': '003', 'address.aName': '上海'}})
result = users_col.find(condition)
for each in result:
    print(each) 

练习12:

用户的年龄有多少种(最后输出数字,提示:可使用python的len())

解答

name = users_col.distinct('age')
print(len(name))

练习13:

删除所有country在USA或者年龄小于等于26岁的用户

解答

condition = {
    '$or': [
        {'country': 'USA'},
        {'age': {'$lte': 26}},

    ]

}
users = users_col.delete_many(condition)
result = users_col.find({},{'_id':0})
for each in result:
    print(each) 

练习14:

根据示例程序,完成下述程序待填充的部分。 两个函数:update_to_mongo、delete_many_to_mongo 四个CRUD操作:(#待填充 语句)

class userTable(object):
    def __init__(self, _id, name, age, country, height, favorites):
        self._id = _id
        self.name = name
        self.age = age
        self.country = country
        self.height = height
        self.favorites = favorites

# 插入一条文档
def insert_one_to_mongo(user):
    users_col.insert_one(user.__dict__)

# 根据条件从mongodb中查询文档
def query_from_mongo(condition):
    #查询
    result = users_col.find(condition)
    #将查询结果转换为pyhton对象
    user_list = []
    for doc in result:
        temp = userTable(doc['_id'],doc['name'],doc['age'],doc['country'],doc['height'],doc['favorites'])
        user_list.append(temp)
    return user_list

#根据条件和更新操作,对文档进行更新
def update_to_mongo(condition, operation):
    #待填充

#根据条件删除文档
def delete_many_to_mongo(condition):
    #待填充

if __name__=='__main__':
    
    #首先删除users_col全部的数据
    delete_many_to_mongo({})
    
    #构造两条数据
    user1 = userTable('001', 'lilei', 28, 'China', 1.81, {'books':['谁动了我的奶酪','飘']})
    user2 = userTable('002', 'hanmeimei', 30, 'China',1.70, {'movies':['头号玩家','肖申克的救赎']})
    user3 = userTable('003', 'zhangsan', 21, 'China',1.76, {'books':['人类简史','CASPP']})
    
    #插入两条数据
    insert_one_to_mongo(user1)
    insert_one_to_mongo(user2)
    insert_one_to_mongo(user3)
    
    #根据查询条件查询文档(查询年龄大于25岁且身高高于1.75的用户)
    user_list = query_from_mongo({})   #待填充  
    
    #输出结果
    print('修改之前\n')
    for s in user_list:
        print(s.__dict__) #lilei
    
    #将hanmeimei的身高改为1.76。
    update_to_mongo({}, {})            #待填充
    
    #根据查询条件查询文档(查询年龄大于25岁且身高高于1.75的用户)
    user_list = query_from_mongo({})   #待填充  
    
    print('\n修改之后\n')
    #输出结果
    for s in user_list:
        print(s.__dict__) #lilei & hanmeimei
        
    #删除喜欢书籍的用户
    delete_many_to_mongo({})           #待填充
    
    #查询剩余全部用户
    user_list = query_from_mongo({})
    
    print('\n删除之后\n')
    #输出结果
    for s in user_list:
        print(s.__dict__) #hanmeimei

解答

class userTable(object):
    def __init__(self, _id, name, age, country, height, favorites):
        self._id = _id
        self.name = name
        self.age = age
        self.country = country
        self.height = height
        self.favorites = favorites

# 插入一条文档
def insert_one_to_mongo(user):
    users_col.insert_one(user.__dict__)

# 根据条件从mongodb中查询文档
def query_from_mongo(condition):
    #查询
    result = users_col.find(condition)
    #将查询结果转换为pyhton对象
    user_list = []
    for doc in result:
        temp = userTable(doc['_id'],doc['name'],doc['age'],doc['country'],doc['height'],doc['favorites'])
        user_list.append(temp)
    return user_list

#根据条件和更新操作,对文档进行更新
def update_to_mongo(condition, operation):
    #待填充
    users_col.update_many(condition, operation)

#根据条件删除文档
def delete_many_to_mongo(condition):
    #待填充
    users_col.delete_many(condition)

if __name__=='__main__':
    
    #首先删除users_col全部的数据
    delete_many_to_mongo({})
    
    #构造两条数据
    user1 = userTable('001', 'lilei', 28, 'China', 1.81, {'books':['谁动了我的奶酪','飘']})
    user2 = userTable('002', 'hanmeimei', 30, 'China',1.70, {'movies':['头号玩家','肖申克的救赎']})
    user3 = userTable('003', 'zhangsan', 21, 'China',1.76, {'books':['人类简史','CASPP']})
    
    #插入两条数据
    insert_one_to_mongo(user1)
    insert_one_to_mongo(user2)
    insert_one_to_mongo(user3)
    
    #根据查询条件查询文档(查询年龄大于25岁且身高高于1.75的用户)
    user_list = query_from_mongo({
        'age': {'$gt': 25},
        'height': {'$gt': 1.75}
    })   #待填充  
    
    #输出结果
    print('修改之前\n')
    for s in user_list:
        print(s.__dict__) #lilei
    
    #将hanmeimei的身高改为1.76。
    update_to_mongo({
        'name': 'hanmeimei'
    }, {
        '$set': {'height': 1.76}
    })            #待填充
    
    #根据查询条件查询文档(查询年龄大于25岁且身高高于1.75的用户)
    user_list = query_from_mongo({
        'age': {'$gt': 25},
        'height': {'$gt': 1.75}
    })   #待填充  
    
    print('\n修改之后\n')
    #输出结果
    for s in user_list:
        print(s.__dict__) #lilei & hanmeimei
        
    #删除喜欢书籍的用户
    delete_many_to_mongo({
        'favorites.books': {'$exists': True}
    })           #待填充
    
    #查询剩余全部用户
    user_list = query_from_mongo({})
    
    print('\n删除之后\n')
    #输出结果
    for s in user_list:
        print(s.__dict__) #hanmeimei




是否对你有帮助?