尝试使用MongoEngine探索MongoDB基础知识
这篇文章是《MongoDB Advent Calendar 2013》的第三天。
MongoEngine是什么?
MongoEngine 是一种 ODM(对象文档映射器),它是为了方便地以类似对象的方式操作MongoDB文档而设计的库。它可以抽象化文档的模式定义、获取和保存功能。
利用方法与Django的ORM非常相似,如果你是Django用户,即使不学习MongoDB特有的查询语法,也可以使用MongoDB。可能的话。
然而,如果想要深入了解并进行进一步操作,就需要具备对MongoDB的了解。
在MongoEngine中可以做什么,又有哪些不能做的事情?
可以做的事情 zuò de
-
- ドキュメントスキーマの定義、制約の定義
-
- ドキュメントの保存
-
- ドキュメントの取得
- カスタムクエリの発行
不能做的事情 or 麻煩的事情
-
- バックアップ&リストアなどシステムレベルのコマンド実行
- MongoDB固有のコマンド発行(出来なくも無いけど、とても面倒)
让我们来碰一下吧
安装
因为已经在PyPI上注册了,所以可以使用pip进行安装。
$ pip install mongoengine
连接设置
连接到MongoDB时,请使用mongoengine.connect。要连接到名为mongotest的数据库,请按照以下方式操作。
from mongoengine import connect
connect('mongotest')
如果需要指定主机或端口,请添加参数。
connect('mongotest', host='192.168.0.10', port=999)
创建文档类
定义一个继承自mongoengine.document.Document类的子类。每个字段都分配了mongoengine.fields.*。字段类的命名类似于Python对象名,例如IntField或StringField。
from mongoengine.document import Document
from mongoengine import fields
class Athlete(Document):
name = fields.StringField()
age = fields.IntField()
def __unicode__(self):
return self.name
MongoDB的一个优点是它是无模式的,但个人而言,我认为创建文档类==模式并对其进行操作更容易。顺便说一下,由于可以在一个集合中操作多个文档类,因此无模式的优点并未受到破坏。
添加文档
实例化Athlete类并调用save()方法。
from documents import Athlete
# taro yamadaとhanako yamadaを追加する
athlete = Athlete(name=u"taro yamada", age=30)
athlete.save()
athlete = Athlete(name=u"hanako yamada", age=28)
athlete.save()
当我使用mongo命令进行查看时……
$ mongo mongotest
MongoDB shell version: 2.4.6
connecting to: mongotest
> show dbs
local 0.078125GB
mongotest 0.203125GB
数据库已经被自动创建了。至于集合,则是
> show collections
athlete
system.indexes
> db.athlete.find()
{ "_id" : ObjectId("529db366bdbf568299123013"), "name" : "taro yamada", "age" : 30 }
{ "_id" : ObjectId("529db458bdbf568299123014"), "name" : "hanako yamada", "age" : 28 }
就像这样,运动员集合中保存了文档。
获取文件
我们可以通过Athlete类来操作获取文档。请通过objects属性调用all()方法获取所有文档(这在Django用户中已经很熟悉了吧)。
>>> Athlete.objects.all()
[<Athlete: taro yamada>, <Athlete: hanako yamada>]
要添加筛选条件,您可以使用filter()方法。
>>> Athlete.objects.filter(age=28)
[<Athlete: hanako yamada>]
如果只需要获取一个文档,可以使用get()方法。
>>> Athlete.objects.get(age=28)
<Athlete: hanako yamada>
在调用get()方法时,如果文档不存在,将会抛出异常。
>>> Athlete.objects.get(name=u"inoki")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/key/.virtualenvs/mongoenginetest/lib/python2.7/site-packages/mongoengine/queryset/base.py", line 186, in get
raise queryset._document.DoesNotExist(msg)
documents.DoesNotExist: Athlete matching query does not exist.
为了计算文档数量,也可以使用count()方法。
>>> Athlete.objects.all().count()
2
文件的更新
在中文中,更新文件可以通过执行实例的save()方法来完成。如果文件不存在,则会被添加,如果存在,则会被更新。
>>> athlete = Athlete.objects.get(name=u"taro yamada")
>>> athlete.age = 50
>>> athlete.save()
<Athlete: taro yamada>
>>> athlete.age
50
删除文件
对于Athlete类的实例,发出delete()方法。
>>> hanako = Athlete.objects.get(age=28)
>>> hanako.delete()
>>> Athlete.objects.all()
[<Athlete: taro yamada>]
“汉子已经被删除了:)”
如果在all()方法后面链式调用delete()方法,所有的内容都会被删除掉(使用filter()方法时也是同样的情况)。
>>> Athlete.objects.all().delete()
>>> Athlete.objects.all()
[]
芋头也已被删除:)