Prerequisites

import pymongo

Making a Connection with MongoClient

>>> from pymongo import MongoClient
>>> client = MongoClient()

连接到默认主机和端口:>>> client = MongoClient('localhost', 27017)
使用URI格式连接:>>> client = MongoClient('mongodb://localhost:27017/')

Getting a Database

通过MongoClient对象的属性访问数据库:>>> db = client.test_database
通过字典风格访问数据库:>>> db = client['test-database']

Getting a Collection

通过属性风格访问集合:>>> collection = db.test_collection
通过字典风格访问集合:>>> collection = db['test-collection']
列出数据库中所有集合:>>> db.list_collection_names()

Documents

MongoDB中的数据使用JSON风格的文档存储和表示。PyMongo中使用字典表示文档。文档可以包含PYTHON原生类型(比如datetime.datetime)会自动转换位合适的BSON类型。

>>> import datetime
>>> post = {"author": "Mike",
...         "text": "My first blog post!",
...         "tags": ["mongodb", "python", "pymongo"],
...         "date": datetime.datetime.utcnow()}

Inserting a Document

当文档被插入a special key,_id会自动添加,如果文档没包含_id键。insert_one返回InsertOneResult实例。

>>> posts = db.posts
>>> post_id = posts.insert_one(post).inserted_id
>>> post_id
ObjectId('...')

Getting a Single Document

最基本查询的函数是find_one。该函数返回匹配查询的一个文档(如果没有,返回None)。

>>> import pprint
>>> pprint.pprint(posts.find_one())
{u'_id': ObjectId('...'),u'author': u'Mike',u'date': datetime.datetime(...),u'tags': [u'mongodb', u'python', u'pymongo'],u'text': u'My first blog post!'}

条件查询

>>> pprint.pprint(posts.find_one({"author": "Mike"}))
{u'_id': ObjectId('...'),u'author': u'Mike',u'date': datetime.datetime(...),u'tags': [u'mongodb', u'python', u'pymongo'],u'text': u'My first blog post!'}

Querying By ObjectId

>>> post_id
ObjectId(...)
>>> pprint.pprint(posts.find_one({"_id": post_id}))
{u'_id': ObjectId('...'),u'author': u'Mike',u'date': datetime.datetime(...),u'tags': [u'mongodb', u'python', u'pymongo'],u'text': u'My first blog post!'}

ObjectId和其字符串表示不一样,不能用于作为查询条件

>>> post_id_as_str = str(post_id)
>>> posts.find_one({"_id": post_id_as_str}) # No result
>>>

web应用从请求的URL中获取ObjectId,查找匹配文档。通过ObjectId构造函数将字符串转换为ObjectId对象

from bson.objectid import ObjectId
# The web framework gets post_id from the URL and passes it as a string
def get(post_id):# Convert from string to ObjectId:document = client.db.collection.find_one({'_id': ObjectId(post_id)})

你可能注意到常规Python字符串和从数据库中取出的字符串不同(比如 u’Mike’而不是’Mike’)。MongoDB将数据以BSON格式存储。BSON字符串是UTF-8编码,所以PyMongo必须确保其存储的任何字符串只包含UTF-8数据。常规字符串(类型为str)可以通过校验并且可以不加改变地存储进数据库,Unicode字符串(类型为unicode)需要先被编码成UTF-8,然后才能存储进数据库。由于PyMongo将BSON字符串解码为PYTHON unicode字符串而不是常规字符串,所以从数据库中取出的字符串是 u’Mike’而不是’Mike’。

Bulk Inserts

使用insert_many进行块插入操作

>>> new_posts = [{"author": "Mike",
...               "text": "Another post!",
...               "tags": ["bulk", "insert"],
...               "date": datetime.datetime(2009, 11, 12, 11, 14)},
...              {"author": "Eliot",
...               "title": "MongoDB is fun",
...               "text": "and pretty easy too!",
...               "date": datetime.datetime(2009, 11, 10, 10, 45)}]
>>> result = posts.insert_many(new_posts)
>>> result.inserted_ids
[ObjectId('...'), ObjectId('...')]

例子中的insert_many返回两个ObjectId实例,每个文档对应一个。

Querying for More Than One Document

使用find方法获取多个文档,该方法返回游标实例,允许我们迭代取出所有匹配文档。

>>> for post in posts.find():
...   pprint.pprint(post)
...
{u'_id': ObjectId('...'),u'author': u'Mike',u'date': datetime.datetime(...),u'tags': [u'mongodb', u'python', u'pymongo'],u'text': u'My first blog post!'}
{u'_id': ObjectId('...'),u'author': u'Mike',u'date': datetime.datetime(...),u'tags': [u'bulk', u'insert'],u'text': u'Another post!'}
{u'_id': ObjectId('...'),u'author': u'Eliot',u'date': datetime.datetime(...),u'text': u'and pretty easy too!',u'title': u'MongoDB is fun'}

可以通过传入文档筛选返回结果

>>> for post in posts.find({"author": "Mike"}):
...   pprint.pprint(post)
...
{u'_id': ObjectId('...'),u'author': u'Mike',u'date': datetime.datetime(...),u'tags': [u'mongodb', u'python', u'pymongo'],u'text': u'My first blog post!'}
{u'_id': ObjectId('...'),u'author': u'Mike',u'date': datetime.datetime(...),u'tags': [u'bulk', u'insert'],u'text': u'Another post!'}

Counting

可以通过count_documents函数查看匹配文档的数量

>>> posts.count_documents({})
3
>>> posts.count_documents({"author": "Mike"})
2

Range Queries

>>> d = datetime.datetime(2009, 11, 12, 12)
>>> for post in posts.find({"date": {"$lt": d}}).sort("author"):
...   pprint.pprint(post)
...
{u'_id': ObjectId('...'),u'author': u'Eliot',u'date': datetime.datetime(...),u'text': u'and pretty easy too!',u'title': u'MongoDB is fun'}
{u'_id': ObjectId('...'),u'author': u'Mike',u'date': datetime.datetime(...),u'tags': [u'bulk', u'insert'],u'text': u'Another post!'}

Indexing

为key创建unique索引

>>> result = db.profiles.create_index([('user_id', pymongo.ASCENDING)],
...                                   unique=True)
>>> sorted(list(db.profiles.index_information()))
[u'_id_', u'user_id_1']

从index_information返回可以看出两个索引:一个是_id由MongoDB自动创建,一个是我们刚刚给user_id创建的索引。

>>> user_profiles = [
...     {'user_id': 211, 'name': 'Luke'},
...     {'user_id': 212, 'name': 'Ziltoid'}]
>>> result = db.profiles.insert_many(user_profiles)

索引会阻止我们插入user_id已经存在的文档

>>> new_profile = {'user_id': 213, 'name': 'Drew'}
>>> duplicate_profile = {'user_id': 212, 'name': 'Tommy'}
>>> result = db.profiles.insert_one(new_profile)  # This is fine.
>>> result = db.profiles.insert_one(duplicate_profile)
Traceback (most recent call last):
DuplicateKeyError: E11000 duplicate key error index: test_database.profiles.$user_id_1 dup key: { : 212 }

https://pymongo.readthedocs.io/en/stable/tutorial.html