pymongo 学习记录

pymongo 是 mongodb 的 python Driver Editor.
记录下学习过程中感觉以后会常用多一些部分,以做参考。

1. 连接数据库

要使用pymongo最先应该做的事就是先连上运行中的 mongod 。

  • 创建一个 .py 文件,首先导入 pymongo:
from pymongo import MongoClient
  • 创建一个连接到 mongod 到客户端:
client = MongoClient()
或者:
client = MongoClient("mongodb://mongodb0.example.net:27019")
  • 连接数据库:
# 假设要连接的数据库名为 primer
db = client.primer
或者:
db = client['primer']
  • 连接到对应的数据集:
coll = db.dataset
coll = db['dataset']

至此,已经完整对连接了数据库和数据集,完成了初识化的操作。

2. 插入数据

> insert_one(document)
> insert_many(documents, ordered=True)
  • insert_one(document)
    在 pymongo 中的插入函数并不像 mongo shell 中完全一样,所以需要注意一下:
from datetime import datetime
result = db.restaurants.insert_one(
    {
        "address": {
            "street": "2 Avenue",
            "zipcode": "10075",
            "building": "1480",
            "coord": [-73.9557413, 40.7720266]
        },
        "borough": "Manhattan",
        "cuisine": "Italian",
        "grades": [
            {
                "date": datetime.strptime("2014-10-01", "%Y-%m-%d"),
                "grade": "A",
                "score": 11
            },
            {
                "date": datetime.strptime("2014-01-16", "%Y-%m-%d"),
                "grade": "B",
                "score": 17
            }
        ],
        "name": "Vella",
        "restaurant_id": "41704620"
    }
)

其中返回的结果:result 中是一个:InsertOneResult 类:
class pymongo.results.InsertOneResult(inserted_id, acknowledged)
其中 inserted_id 是插入的元素多 _id 值。

  • insert_many(documents, ordered=True)
result = db.test.insert_many([{'x': i} for i in range(2)])

3. 查询数据

> find(filter=None, projection=None, skip=0, limit=0,
        no_cursor_timeout=False, cursor_type=CursorType.NON_TAILABLE,
        sort=None, allow_partial_results=False, oplog_replay=False,
        modifiers=None, manipulate=True)
> find_one(filter_or_id=None, *args, **kwargs)
  • find
    find 查询出来的是一个列表集合。
cursor = db.restaurants.find()
for document in cursor:
    print(document)
# 查询字段是最上层的
cursor = db.restaurants.find({"borough": "Manhattan"})
# 查询字段在内层嵌套中
cursor = db.restaurants.find({"address.zipcode": "10075"})
  • 操作符查询
cursor = db.restaurants.find({"grades.score": {"$gt": 30}})
cursor = db.restaurants.find({"grades.score": {"$lt": 10}})
# AND
cursor = db.restaurants.find({"cuisine": "Italian", "address.zipcode": "10075"})
cursor = db.restaurants.find(
    {"$or": [{"cuisine": "Italian"}, {"address.zipcode": "10075"}]})
  • find_one
    返回的是一个JSON式文档,所以可以直接使用!

  • sort
    排序时要特别注意,使用的并不是和mongo shell的一样,而是使用了列表,
    当排序的标准只有一个,且是递增时,可以直接写在函数参数中:

pymongo.ASCENDING = 1
pymongo.DESCENDING = -1
cursor = db.restaurants.find().sort("borough")
cursor = db.restaurants.find().sort([
    ("borough", pymongo.ASCENDING),
    ("address.zipcode", pymongo.DESCENDING)
])

4. 更新文档

更新文档的函数有三个(不能更新 _id 字段)

update_one(filter, update, upsert=False)
update_many(filter, update, upsert=False)
replace_one(filter, replacement, upsert=False) 
find_one_and_update(filter, update, projection=None, sort=None, return_document=ReturnDocument.BEFORE, **kwargs)
  • update_one
    返回结果是一个:UpdateResult,如果查找到多个匹配,则只更新
    第一个!
result = db.restaurants.update_one(
    {"name": "Juni"},
    {
        "$set": {
            "cuisine": "American (New)"
        },
        "$currentDate": {"lastModified": True}
    }
)
result.matched_count
10
result.modified_count
1
  • update_many
    查找到多少匹配,就更新多少。
result = db.restaurants.update_many(
    {"address.zipcode": "10016", "cuisine": "Other"},
    {
        "$set": {"cuisine": "Category To Be Determined"},
        "$currentDate": {"lastModified": True}
    }
)
result.matched_count
20
result.modified_count
20
  • replace_one
result = db.restaurants.replace_one(
    {"restaurant_id": "41704620"},
    {
        "name": "Vella 2",
        "address": {
            "coord": [-73.9557413, 40.7720266],
            "building": "1480",
            "street": "2 Avenue",
            "zipcode": "10075"
        }
    }
)
result.matched_count
1
result.modified_count
1
  • find_one_and_update
    返回更新前的文档
db.test.find_one_and_update(
    {'_id': 665}, {'$inc': {'count': 1}, '$set': {'done': True}})
{u'_id': 665, u'done': False, u'count': 25}}

5. 删除文档

删除时主要有两个:

> delete_one(filter)
> delete_many(filter)
> drop()
> find_one_and_delete(filter, projection=None, sort=None, **kwargs)
> find_one_and_replace(filter, replacement, projection=None,
>       sort=None, return_document=ReturnDocument.BEFORE, **kwargs)
  • delete_one
result = db.test.delete_one({'x': 1})
result.deleted_count
1
  • delete_many
result = db.restaurants.delete_many({"borough": "Manhattan"})
result.deleted_count
10259
# 删除全部
result = db.restaurants.delete_many({})
  • drop()
    删除整个集合,是drop_collection()的别名
db.restaurants.drop()
  • find_one_and_delete
db.test.count({'x': 1})
2
db.test.find_one_and_delete({'x': 1})
{u'x': 1, u'_id': ObjectId('54f4e12bfba5220aa4d6dee8')}
db.test.count({'x': 1})
  • find_one_and_replace
>>> for doc in db.test.find({}):
...     print(doc)
...
{u'x': 1, u'_id': 0}
{u'x': 1, u'_id': 1}
{u'x': 1, u'_id': 2}
>>> db.test.find_one_and_replace({'x': 1}, {'y': 1})
{u'x': 1, u'_id': 0}
>>> for doc in db.test.find({}):
...     print(doc)
...
{u'y': 1, u'_id': 0}
{u'x': 1, u'_id': 1}
{u'x': 1, u'_id': 2}

6. 索引操作

索引主要有创建索引和删除索引:

> create_index(keys, **kwargs)
> create_indexes(indexes)
> drop_index(index_or_name)
> drop_indexes()
> reindex()
> list_indexes()
> index_information()
  • create_index
my_collection.create_index("mike")
my_collection.create_index([("mike", pymongo.DESCENDING),
...                             ("eliot", pymongo.ASCENDING)])
my_collection.create_index([("mike", pymongo.DESCENDING)],
...                            background=True)
  • create_indexes
>>> from pymongo import IndexModel, ASCENDING, DESCENDING
>>> index1 = IndexModel([("hello", DESCENDING),
...                      ("world", ASCENDING)], name="hello_world")
>>> index2 = IndexModel([("goodbye", DESCENDING)])
>>> db.test.create_indexes([index1, index2])
["hello_world"]
  • drop_index
    index_or_name: 索引编号或者索引的name
my_collection.drop_index("mike")
  • drop_indexs
    删除所有索引

  • reindex
    重构索引,尽量少用,如果集合比较大多话,会很耗时耗力.

for index in db.test.list_indexes():
...     print(index)
...
SON([(u'v', 1), (u'key', SON([(u'_id', 1)])),
     (u'name', u'_id_'), (u'ns', u'test.test')])
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,099评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,828评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,540评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,848评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,971评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,132评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,193评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,934评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,376评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,687评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,846评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,537评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,175评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,887评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,134评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,674评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,741评论 2 351

推荐阅读更多精彩内容