首先导入:

from pymongo import MongoClient

连接mongodb:

没有密码的连接方式
mongo_client = MongoClient(mongo_host, mongo_port, connect=False)
有密码的认证登录方式:
self.client = pymongo.MongoClient(host="127.0.0.1", port=27017, username="user name", password="pass/word")

连接数据库:例如连接my_db数据库,没有则自动创建

mongo_db = mongo_client["my_db"]
# 或者下面这样也可以
mongo_db = mongo_client.my_db

使用集合:例如使用my_set集合,没有则自动创建

coll = mongo_db["my_set"]
# 或者下面这样也可以
coll = mongo_db.my_set

接下来是集合里面的操作

1、基本操作

(1)查找

parmas = {"age": 16, "address": "beijing"}
if params is None:
    cursors = coll.find()
else:
    cursors = coll.find(params)

find()内不传参时是查找的整个集合的数据,也可以通过字典传参精确查找,精确查找出来的可能没有,可能是一个,也可能是多个,无论一个还是多个,都是列表生成器对象,需要按照列表的操作方法取出来(也可以使用list方法强转列表)。

for cursor in cursors:
通过循环每一条数据进行操作
也可以按列表索引取值

条件查找操作符

符号

含义

示例

示例含义

$lt

小于

{‘age’: {’$lt’: 20}}

年龄小于20

$gt

大于

{‘age’: {’$gt’: 20}}

年龄大于20

$lte

小于等于

{‘age’: {’$lte’: 20}}

年龄小于等于20

$gte

大于等于

{‘age’: {’$gte’: 20}}

年龄大于等于20

$ne

不等于

{‘age’: {’$ne’: 20}}

年龄不等于20

$in

在范围内

{‘age’: {’$in’: [20, 23]}}

年龄在20到30的范围内

$nin

不在范围内

{‘age’: {’$nin’: [20, 23]}}

年龄不在20到30的范围内

$or

或条件

{"$or":[{“age”:30},{“address”: “nanjing”}]}

年龄30岁或者地址是nangjing的

$and

且条件

and基本不用,因为相当于find()内传字典时,传入多对键值对而已,例{“name”: “laowang”, “age”: 40}

查找集合中年龄大于15小于20的所有数据
cursors = coll.find({"age": {"$gt": 15, "$lt": 20}})
功能符号归类如下:

符号

含义

示例

示例含义

$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’}

自身粉丝数等于关注数

正则匹配name字段以M开头的数据

例如查询名字以M开头的学生数据,示例如下:
result = coll.find({“name”: {"$regex": “^M.*”}})

查找某个字段是某种类型的
#找出name的类型是String的

cursors = coll.find({"name": {'$type': 2}})

#类型 值
Double 1
String 2
Object 3
Array 4
Binary data 5
Undefined 6 已废弃
Object id 7
Boolean 8
Date 9
Null 10
Regular Expression 11
JavaScript 13
Symbol 14
JavaScript (with scope) 15
32-bit integer 16
Timestamp 17
64-bit integer 18
Min key 255 Query with -1.
Max key 127

find_one: 查找一条数据,用法和find相同,但是结果返回的是这条数据的字典结构

对查找出来的数据进行排序

使用sort()方法对数据进行排序,sort()方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序,-1为降序。
这里升序的1也可以使用pymongo.ASCENDING,降序的-1也可以使用pymongo.DESCENDING
cursors = coll.find().sort([("age", 1), ("student_id", -1)])
cursors = coll.find().sort([("age", pymongo.ASCENDING), ("student_id", pymongo.DESCENDING)])

偏移:某些情况下,我们想取查询出来的数据中忽略掉前几个,可以使用skip()

偏移

cursors = coll.find().skip(2)

注:在数据量非常庞大的时候,如千万、亿级,最好不要使用大的偏移量来查询数据,很可能会导致内存溢出,可以使用类似
cursors = coll.find({"_id": {"$gt": ObjectId(“5c6a52868b8c3c6f24ea5edb”)}})
这样的方法来查询,记录好上次查询的_id

限制数据条数:某些情况下我们只想取查出来的前几个,可以使用limit()

值得注意的是,在数据库数量非常庞大的时候,如千万、亿级别,最好不要使用大的偏移量来查询数据,很可能会导致内存溢出,可以使用类似find({’_id’: {’$gt’: ObjectId(‘593278c815c2602678bb2b8d’)}}) 这样的方法来查询,记录好上次查询的_id

只取前10条数据

cursors = coll.find().limit(10)
计数统计
nums = coll.find().count()

以上方法可以组合使用

(2) 插入数据

insert、insert_one、insert_many

insert: 可以插入一条数据,也可以插入多条数据,拥有insert_one和insert_many的功能,但是官方在python3的版本中已经不推荐使用了,推荐使用后两个,当然仍然使用也没问题,insert在插入一条数据的时候,会返回插入数据的_id,插入多条时候,会返回一个_id列表。
result = coll.insert({“name”: “laowang”, “age”: 40}) # 结果会返回插入数据的_id
result = coll.insert([{“name”: “laowang”, “age”: 40}, {“name”: “lisi”, “age”: 41}, {“name”: “wangwu”, “age”: 42}])

结果返回一个列表,里面包含插入所有数据的_id

insert_one: 插入一条数据,和insert插入一条数据用法相同,只不过返回的结果是个InsertOneResult对象,我们可以调用inserted_id属性获取_id。

insert_many: 插入多条数据,和insert插入多条数据用法相同,只不过返回的结果是个InsertOneResult对象,我们可以调用inserted_ids属性获取_id列表

(3)更新

update()、update_one()、update_many() 更新时如无此字段,则会添加
update() 同insert一样,它兼具了后两个的功能,也是官方已经不推荐使用了,推荐使用后两个
这里讲下update_one和update_many的使用吧
update_one(): 此方法只匹配查出来的第一条数据去进行更新

把laowang的年龄改为42,address改为nanjing

condition = {"name": "laowang"}
update = {"$set": {"age": 42, "address": "nanjing"}}
result = coll.update(filter=condition, update=update)
返回的结果是UpdateResult类型,调用match_count和modified_count属性分别可以获得匹配的数据条数和影响的数据条数

高级一点的用法:

把老王的年龄加1

condition = {"name": "laowang"}
update = {"$inc": {"age": 1}}
result = coll.update(filter=condition, update=update)

update_many(): 使用同update_one(), 但是它会更新所有匹配出来的数据

(4)删除

remove: 使用比较简单,调用时会把符合条件的所有数据全部删除,同insert一样,也有两个新的推荐使用方法,delete_one和delete_many

remove会删除所有匹配到的数据,返回结果是执行结果状态和执行的条数
result = coll.remove({"age": 20})
delete_one:只删除匹配的第一条数据,返回结果是DeleteResult对象,可以调用deleted_count属性获取删除数据的条数
result = coll.delete_one({"age": 20})

delete_many:只删除匹配的第一条数据,返回结果是DeleteResult对象,可以调用deleted_count属性获取删除数据的条数

result = coll.delete_many({"age": 20})

(5)distinct
查找某个字段有多少种类

查找数据表中,所有人中,一共有多少个省份的人,假如50人,有20个省份的人,则查询后返回的是一个列表,列表中包含所有的省份,但不重复
result = coll.distinct("address")


2 高级用法

(1)高级查找: aggregate

query_param = {}
match_params = {"$match": query_param}
group = {"_id": {},
        "total_integral": {"$sum": "$integral"},
         }
group_params = {"$group": group}
sort = {
        "_id.student_id": pymongo.ASCENDING,
        "_id.age": pymongo.ASCENDING
}
sort_params = {"$sort": sort}
result = coll.aggregate([match_params, group_params, sort_params])

(2)高级操作
bulk_write
待完成

3 加索引

为字段创建索引, 其中的1和-1分别表示正序与负序排列,创建唯一索引,不加unique=True的话默认是普通的索引,即unique=False
create_index 和 ensure_index,用法相同,ensure_index在pymongo3.0已弃用,推荐使用create_index
key_list = [(“索引字段名1”, 1), (“索引字段名2”, 1), (“索引字段名3”, 1),]
coll.create_index(key_list, unique=True)
使用create_index或则ensure_index创建与之前“唯一性unique”不同的同名索引,会出现“OperationFailure”错误。
解决方法:
首先,判断有无同名索引;然后判断同名索引是否为唯一索引;
若有同名索引,且非唯一索引,则删除已有的同名索引,然后重新建立索引。

from pymongo import MongoClient


def create_unique_index():
    """
    创建唯一索引
    :return:
    """
    coll = MongoClient('localhost').get_database('test_db').get_collection('test_col_1')
    all_index = coll.index_information()
    print
    all_index  # 打印所有索引信息

    has_id_index = all_index.get("id_1", False)  # 判断有无“id”索引
    if has_id_index:
        if all_index['id_1'].get('unique', False):  # id为唯一索引
            pass
        else:
            coll.drop_index([("id", 1)])
            coll.create_index([("id", 1)], unique=True)  # 尝试创建唯一索引
    else:
        coll.create_index([("id", 1)], unique=True)  # 尝试创建唯一索引


if __name__ == "__main__":
    create_unique_index()

未完,待续。。。。。。。。