使用MongoEngine接触MongoDB的基础知识


本文是MongoDB Advent Calendar 2013的第三天。

什么是MongoEngine?

MongoEngine是一个名为ODM == Object Document Mapper的库,它使您可以为MongoDB之类的对象处理文档。它抽象了文档架构的定义,检索和存储。

用法与Django的ORM非常相似,并且Django用户无需学习MongoDB特定查询即可使用MongoDB。也许。

但是,尝试做一些深入的事情需要MongoDB的知识。

MongoEngine可以做什么和不能做什么

你能做什么

  • 文档架构定义,约束定义
  • 保存文件
  • 获取文档
  • 发出自定义查询

您不能做什么或麻烦

  • 系统级命令执行,例如备份和还原
  • 发出特定于MongoDB的命令(不是不可能,但很麻烦)

让我们触摸

安装

由于它已在

pypi中注册,因此请使用pip安装它。

1
$ pip install mongoengine

连接目的地设置

使用mongoengine.connect连接到MongoDB。要连接到名为mongotest的数据库:

1
2
3
from mongoengine import connect

connect('mongotest')

在指定主机或端口时添加参数。

1
connect('mongotest', host='192.168.0.10', port=999)

创建文档类

定义一个继承

mongoengine.document.Document类的子类。将mongoengine.fields.*分配给每个字段。使用与python对象名称相似的名称定义字段类,例如IntField和StringField。

documents.py

1
2
3
4
5
6
7
8
9
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很好,因为它没有模式,但是我个人发现创建和操作文档类==模式更加容易。顺便说一句,一个集合可以处理多个文档类,因此不会破坏无模式的好处。

添加文档

实例化

运动员类,然后调用save()方法。

1
2
3
4
5
6
7
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命令...

1
2
3
4
5
6
7
$ mongo mongotest
MongoDB shell version: 2.4.6
connecting to: mongotest

> show dbs
local   0.078125GB
mongotest   0.203125GB

数据库是自动创建的。集合是

1
2
3
4
5
6
7
> show collections
athlete
system.indexes

> db.athlete.find()
{ "_id" : ObjectId("529db366bdbf568299123013"), "name" : "taro yamada", "age" : 30 }
{ "_id" : ObjectId("529db458bdbf568299123014"), "name" : "hanako yamada", "age" : 28 }

文档存储在运动员集合中,例如

获取文档

也从运动员班获得文件。让我们通过objects属性(Django用户熟悉的属性)通过all()方法获取所有记录。

1
2
>>> Athlete.objects.all()
[<Athlete: taro yamada>, <Athlete: hanako yamada>]

使用filter()方法添加

采集条件。

1
2
>>> Athlete.objects.filter(age=28)
[<Athlete: hanako yamada>]

如果只想获取一个

文档,则可以使用get()方法。

1
2
>>> Athlete.objects.get(age=28)
<Athlete: hanako yamada>

如果执行

get()方法时文档不存在,则会引发异常。

1
2
3
4
5
6
>>> 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()方法计算

文档的数量。

1
2
>>> Athlete.objects.all().count()
2

文档更新

要更新

文档,请执行实例的save()方法。如果没有文档,将添加该文档,如果有,将对其进行更新。

1
2
3
4
5
6
>>> athlete = Athlete.objects.get(name=u"taro yamada")
>>> athlete.age = 50
>>> athlete.save()
<Athlete: taro yamada>
>>> athlete.age
50

删除文件

运动员类的实例上发出delete()方法。

1
2
3
4
>>> hanako = Athlete.objects.get(age=28)
>>> hanako.delete()
>>> Athlete.objects.all()
[<Athlete: taro yamada>]

hanako已被删除:)

如果不经意地将delete()方法链接到all()方法之后,所有内容都将消失(即使您使用filter())。

1
2
3
>>> Athlete.objects.all().delete()
>>> Athlete.objects.all()
[]

芋头也已被移除:)