文档章节

pymongo tutorial

Hardlighting
 Hardlighting
发布于 2015/04/21 15:48
字数 1834
阅读 185
收藏 1

原版英文文档

教程

这个教程只在介绍如何使用MongoDBPyMongo

准备前提

在我们开始之前,首先确认你已经正确安装了PyMongo ,在python shell 中如果下面的命令没有报错,则证明安装正确

>>>import pymongo

这个教程假设你已经正确安装了MongoDB,而且已经有一个instance运行在默认的host和port,如果你已经正确安装了mongodb可以使用下面进行启动

$mongod

和MongoClient建立连接

使用pymongo的第一步是创建一个MongoClient 用于和运行的mongod实例进行连接

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

上面的代码将会连接默认的Host和port.我们也可以手动指定host 和端口,比如:

>>>client = MongoClient('localhost',27017)

或者使用mongodb url 格式地址:

>>>client = MongoClient('mongodb://localhost:27017/')

获取数据库(Database)

一个mongodb实例可以支持多个独立的databse. 当使用pymongo的时候,你可以使用类似属性风格的方式访问MongoClient实例的database:

>>>db  = client.test_database

或者使用字典风格也可以

>>>db = client['test-database']

获取一个集合(collection)

一个集合(collection)是一系列储存在mongodb上的文档(document)的组,有点类似关系型数据库的表table。获取集合的方法类似获取数据库

>>>collection = db.test_collection

或者使用字典:

>>>collection = db['test-collection']

需要注意的是mongodb中的databases或者documents都是属于延迟创建(lazily created)的,上面所有的commands其实都没有对数据库进行任何实质性的操作。上面代码中的databases或者documents直到第一个documents被添加insert时才被创建

文档(documents)

数据在mongodb里面以JSON风格文档来存储和体现。在pymongo中我们使用字典来体现documents。在下面的例子中字典被用来表现一篇博客:

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

注意 documents可以包含python自己的类型(比如datetime.datetime实例),这些数据会被自动转化为bson类型

添加文档(insert a document)

可以使用insert_one()来添加一条documents:

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

当添加documents时候,如果‘_id’值没有指定,则系统会自动生成一个'_id'值,这个'_id'值在整个collection中是唯一的。inssert_one()返回一个InsertOneResult结果实例。

在添加了第一个document时,posts这个集合才在服务器上真正的创建。我们可以列出database中的集合collection来确认:

>>>db.collection_names(include_system_collections=False)
[u'posts']

使用find_one()来得到一条document

最常使用的查询就是find_one()。他返回一条匹配的文档(如果没有匹配会返回None)。他经常被用在只有一条文档匹配,或者指向得到第一个匹配文档的情况。下面我们用他来返回post集合的第一条文档:

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

返回的结果就是我们刚才添加的那条文档

注意:返回的文档中包含"_id",这是系统自动生成的

可以给find_one()添加一些匹配的参数:

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

如果我们尝试一个不同的author,比如‘Eliot’就得不到结果:

>>> posts.find_one({"author": "Eliot"})
>>>

通过ObjectId查询

我们也可以通过ObjectId进行查询:

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

注意ObjectId并不是一个简单的string

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

当我们进行web开发的时候,经常会需要将url中得到的ObjectId转换成pymongo可以识别的ObjectId,然后将他传递给find_one: from bson.objectid import OjbectId # 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)})

关于Unicode

你可能已经发现了我们刚才保存的常规的Python string和我们从服务器得到的并不一样(比如u'Mike' 'Mike'),这里我们简单的解释一下:

mongodb保存使用BSON 格式来保存数据。BSON string 都是UTF-8编码,所以pymongo必须确保所有的sting必须都是合法的UTF-8数据。常规的string储存不变???(regular string are validated and stored unaltered), Unicode编码的string首先会已utf-8编码。我们例子里面显示为u'Mike'而不是'Mike'的原因就是,pymongo首先解码每个BSON为PYHON unicode string,而不是常规的str (妈的,不懂)

关于pythong unicode string的详细阅读

批量添加 Bulk inserts

可以使用insert_many() 一次性添加多个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
[ObjectId('...'), ObjectId('...')]

关于上面这个例子需要注意两点:

  • 上面例子中insert_many()反悔了两个ObjectId实例,分别对应两个document
  • new_posts[1] 和其他的post的数据结构“shape”是不同的 - 一个有tag属性,一个有title属性,这就是我们常提到mongodb的自由结构(schema-free)特性 区别于传统的关系型数据库

查询得到多个文档

我们可以使用find()来一次性返回多个文档。find()返回一个指针cursor实例,可以用来遍历所有匹配的documents。 例如我可以用它来遍历所有的posts集合的所有documents:

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

就像find_one()一样,我们也可以给他传递参数

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

计数

可以使用count()方法进行计数,而不是返回一个完整的查询

>>> posts.count()
3

或者对返回的查询进行计数

>>> posts.find({"author": "Mike"}).count()
2

范围查询

mongodb支持多种不同类型的高级查询。比如我可以查询一个早于特定时间的posts,然后按照author排序返回

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

这里我们使用“$lt”操作符来做一个范围查询,然后使用sort()来对结果进行排序

索引

如果想让上述查询更快,我们可以给“date” 和"author"属性增加 元素索引。 为了显示增加索引后的效率提升,我们使用explain()方法来得到查询动作的次数:

>>> posts.find({"date": {"$lt": d}}).sort("author").explain()["cursor"]
u'BasicCursor'
>>> posts.find({"date": {"$lt": d}}).sort("author").explain()["nscanned"]
3

可以看到在没有索引的情况下,使用 基本指针basicCursor 总共扫描了集合中的3个文档,现在我们添加索引

>>>from pymongo import ASCENDING, DESCENDING
>>>posts.create_index([("date", DESCENDING), ("author"), ASCENDING])
u'date_-1_author_1'
>>>posts.find({'date':{"$lt":d}}).sort("author").explain(['curosr'])
u'BtreeCursor date_-1_author_1
>>> posts.find({"date": {"$lt": d}}).sort("author").explain()["nscanned"]
2

可以看到这次的衩裙使用 Btree指针 BtreeCursor 只扫描了两个文档就得到了结果

© 著作权归作者所有

共有 人打赏支持
Hardlighting
粉丝 0
博文 58
码字总数 27032
作品 0
浦东
CentOS平台下为Python添加MongoDB支持PyMongo

下载PyMongo [root@leezhen ~]# wget https://pypi.python.org/packages/source/p/pymongo/pymongo-2.6.3.tar.gz 解压PyMongo [root@leezhen ~]# tar zxvf pymongo-2.6.3.tar.gz 进入PyMongo......

leezhen
2014/03/11
0
2
Python操作MongoDB - 极简教程

Python 连接 MongoDB 安装PyMongo模块 使用MongoClient建立连接 获取数据库 获取集合 上述任何命令都没有在MongoDB服务器上实际执行任何操作。当第一个文档插入集合时才创建集合和数据库。 ...

kangvcar
2017/11/02
0
2
mongodb和python的datetime的差异

python中需要使用utc时间 mongo.exe命令 db.sms_ttl.ensureIndex({"createdAt": 1}, {expireAfterSeconds: 600}) pymongo操作 db.smsttl.insert({"createdAt": datetime.utcnow(), "type": ......

flyking
2014/07/30
0
0
Windows平台下为Python添加MongoDB支持PyMongo

到Python官网下载pymongo-2.6.3.win-amd64-py2.7.exe 安装pymongo-2.6.3.win-amd64-py2.7.exe 参照官方的用例进行测试 打开命令提示符,进入Python运行环境。 导入pymongo模块 >>> import p......

leezhen
2014/02/16
0
0
MongoDB在Ubuntu10.04下的单机性能测试

MongoDB是一个基于分布式文件存储的数据库开源项目。由C++语言编写。旨在为WEB应用提供可护展的高性能数据存储解决方案。它比纯noSQL数据库查询功能强悍,比关系数据库更面向集合。 测试的硬...

岭南六少
2011/08/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

67:shell脚本介绍 | shell脚本结构 | 执行data命令用法 | shell脚本中变量

1、shell脚本介绍: shell是一种脚本语言和传统的开发语言相比,会比较简单: shell有自己语法,可以支持逻辑判断、循环等语法: 可以自定义函数,目的是减少重复的代码: shell是系统命令的集合...

芬野de博客
27分钟前
1
0
json schema

json schema是用来验证和描述json对象结构的。 在线验证:https://www.jsonschemavalidator.net/ json schema 编辑器,推荐VSCode,写上"$schema": "https://raw.githubusercontent.com/jso......

谷永权
32分钟前
1
0
部署生产级的 Kubernetes 集群,使用kubespray

部署生产级的 Kubernetes 集群,使用kubespray 项目源码,https://github.com/openthings/kubespray 国内部署,https://github.com/zhangguanzhang/Kubernetes-ansible 欢迎加入 kubernetes......

openthings
39分钟前
0
0
73.分发系统介绍 expect脚本远程登录 执行命令 传递参数

20.27 分发系统介绍 20.28 expect脚本远程登录 20.29 expect脚本远程执行命令 20.30 expect脚本传递参数 20.27 分发系统介绍: 场景:业务越来越大。用的比如app,后端(也就是服务器)所使用...

王鑫linux
45分钟前
0
0
SpringBoot应用不能访问项目静态页面html问题处理

问题描述:SpringBoot搭建web应用在eclipse中启动能够正常访问页面,打包成jar之后不能访问到页面,没有任何出错提示。 环境:使用的是前后端分离架构,没有使用模板,前端html和静态文件放到...

奋斗小蜗牛
48分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部