
本文共 5048 字,大约阅读时间需要 16 分钟。
-
pymongo支持MongoDB 2.6, 3.0, 3.2, 3.4, 3.6 and 4.0.
-
-
建立与MongoClient的连接
使用PyMongo的第一步是创建一个MongoClient来运行mongod实例。很简单
from pymongo import MongoClientclient = MongoClient()
上述代码采用默认host和port,我们也可以制定host和port,例如:
client = MongoClient('localhost', 27017)
或者采用MongoDB URL格式:
client = MongoClient('mongodb://localhost:27017/')
-
获取一个数据库Database
一个MongoDB实例可以支持多种独立数据库,当使用pymongo你可以用针对MongoClient实例采用属性风格连接到数据库:
db = client.test_database
如果你的数据库名字是这样的(例如
test-database
),导致无法采用属性方式连接,可以采用字典方式连接:db = client['test-database']
-
获取一个连接Collection
Collection是存储在MongoDB中的一组文档,可以粗略的理解为关系型数据库中的table,在pymongo中实现连接方式与获取数据库一样:
collection = db.test_collection# orcollection = db['test-collection']
MongoDB
中关于collections
和database
有个重要特点:他们都是lazily创建的,上述所有命令都不会对服务器产生实际操作。只有在第一个
document
被嵌入后,Collections
和databases
才会被创建。 -
Documents
MongoDB中的数据采用类JSON格式存储或表示。在PyMongo中我们用字典表示documents。例如下面的字典可以用来表示一个博客帖子:
import datetimepost = { 'author': 'Mike', 'text': 'My first blog post', 'tags': ['Mongodb', 'python', 'pymongo'], 'date': datetime.datetime.utcnow()}
documents
可以含有原生Python类型(例如datetime.datetime
实例),他们可以自动转化为对应的BSON
类型。 -
插入一个Documents
用
insert_one()
方法将一个document
嵌入到collection
中。posts = db.postspost_id = posts.insert_one(post).inserted_id
当一个document被嵌入,如果document不含有‘
_id
’,则一个特定的’_id
‘就自动添加。’_id
‘的值在整个collection中必须是独一无二的。 返回一个实例。关于’_id
'的更多信息,参见 .嵌入第一个document之后,posts这个collection就存在在服务器上了。可以从过列出database上的所有collections来确认:
db.list_collection_names()
-
查询query
-
用 获取一个单独的Document
MongoDB中可执行的最简单的查询(query)就是 . 这个方法返回一个满足条件的单一document(如果没有匹配的就返回None)。在你知道只有一个符合项或只关心第一个符合项的时候,这个方法是很有用的。如下,我们采用 从posts这个collection中获取第一个document:
import pprintpprint.pprint(posts.find_one())
结果是符合条件的我们先前插入的字典。
返回的document包含一个’
_id
’,也就是在嵌入时候自动添加的那个。find_one()也支持特定元素查询,限定满足author是“Mike”的结果:
pprint.pprint(posts.find_one({ 'author':'Mike'}))
如果我们尝试去找另一个作者’Eliot’,没有结果。
-
通过ObjectId查询
我们也可以通过他的’_id’来找一个post,在我们的例子中是ObjectId:
post_idpprint.pprint(posts.find_one({ '_id': post_id}))
一个ObjectId跟它的字符串表示是不一样的,比如:
post_id_as_str = str(post_id)posts.find_one({ '_id': post_id_as_str}) # No Result
在Web应用中一个常见的任务是从请求URL中获取一个
ObjectId
,并找到对应的document
。在这个案例中,在将其传递为find_one
之前把string
转变为ObjectId
是很有必要的。from bson.objectid import ObjectId# web framework从URl中获取post_id并将其转为stringdef get(post_id): # 从string转为ObjectId document = client.db.collection.find_one({ '_id': ObjectId(post_id)})
-
查询多个documens
通过一个查询语句获取多个
document
,采用find()
方法。find()
返回一个Cursor
实例,它可以让我们迭代所有符合的documents。例如,我们可以迭代posts collection
中的每个document
:for post in posts.find(): pprint.pprint(post)
跟
find_one()
一样,我们可以给find()
传递一个document
来限制返回结果。这里,我们只能得到author是'Mike'
的那些documents
:for post in posts.find({ 'author': 'Mike'}): pprint.pprint(post)
-
Range Queries范围查询
MongoDB支持多种类型的高级搜索( ),例如,我们执行某个查询:限定晚于某一特定时期的的帖子,同时将结果按author排序:
d = datetime.datetime(2009, 11, 12, 12)for post in posts.find({ 'date': { '$lt':d}}).sort('author'): pprint.pprint(post)
这里我们采用一个特殊运算符
'$lt'
来做范围查询,同时调用sort()
来对结果按照author
排序。
-
-
关于Unicode 字符串
你可能也留意到了,我们存储的正规Python字符串与从服务器上恢复的字符串看起来不太一样(比如用
u'Mike'
代替了’Mike'
).MongoDB采用BSON格式存储数据,BSON字符串是UTF-8编码,所以PyMondo必须确保它存储的任何字符串只包含合法的UTF-8数据。正规字符串(<type ‘str’>)被验证并原样存储。首先Unicode字符串(<type ‘unicode’>)被编码成UTF-8.在我们的案例中,Python里的’Mike’被替换为u’Mike’的原因是PyMongo将每一个BSON字符串解码为unicode字符串,而非标准字符串。
.
-
批量插入
为了让查询变得更有趣,让我们插入更多documents。除了可以插入单个document,也可以通过传递一个list作为insert_many()的第一个参数,实现
bulk insert
(批量插入)操作。此操作会将list中的每个document都插入数据库,只需要想服务器发送一个命令: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
关于上例,有两个有趣的地方:
- insert_many()的结果返回两个ObjectId实例,插入的document各有一个。
- new_posts[1]与其他posts形状不同:没有’
tags
‘却有’title
’,这就是我们所说的MongDb是模式自由的(Schema-free)
-
计数Counting
如果我们知识想要知道符合查询条件的结果一共有多少,可以采用count_documents()操作,而不用全部查出来。
posts.count_documents({ })
或者只计算那些福特特定查询条件的:
posts.count_documents({ 'author':'Mike'})
-
Indexing索引
增加索引可以加速特定查询,同时为查询和存储documents增加功能。在这个案例中,我们展示如何创建唯一索引( ),拒绝在索引值已存在于索引中的documents。
-
第一步,创建索引
result = db.profiles.create_index([('user_id', pymongo.ASCENDING)], unique = True)sorted(list(db.profiles.index_information()))
现在有两个索引,一个是MongoDb自动船舰的
'_id'
,另一个是刚才创建的’user_id
’。 -
第二步,设置一些用户配置
user_profiles = [{ 'user_id': 211, 'name': 'Luke'}, { 'user_id': 212, 'name': 'Ziltoid'}]result = db.profiles.insert_many(user_profiles)
-
第三步,索引阻止我们插入那些user_id已经在collection中存在的document
>>> 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 }
-
-
发表评论
最新留言
关于作者
