python学习笔记-Mongodb

建立一个MongoClient

第一步我们需要建立一个MongoClient来运行MongoDB,这个做起来非常简单:


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

上面的代码会连接默认的地址和端口,我们也可以自己指定地址和端口,像下面这样:


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

或者使用MongoDB的URI连接:

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

获取数据库

一个MongoDB可以提供多个数据库接口。当使用PyMongo的时候,你可以使用获取属性的方式建立MongoClient:


>>> db = client.test_database

如果你使用上面的方法无法获取数据库的时候,你可以使用字典的方式来获取数据库。
获取连接

获取连接的方式和获取数据库的方式一样,也可以使用获取属性的方式:


>>> collection = db.test_collection

或者使用字典的方式:


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

注意:使用MongoDB建立连接非常容易,但是上面的所有操作都不是实实在在的操作了MongoDB,当第一次获取数据库和建立连接的时候,数据库和连接会被创建。

文档

MongoDB的数据格式存储使用的是JSON风格,在PyMongo中,我们使用的字典类型就相当于数据。比如下面的数据就类似博客中的post信息:


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

数据格式可以容纳python的类型(就像datetime.datetime)

插入数据

往数据库插入一条数据我们使用insert_one()方法:


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

当我们插入数据成功的时候,MongoDB会生成一个特殊的主键“_id”。这个主键“_id”的值是唯一的。insert_one()返回的值就是这个主键的值。

插入第一条数据后,数据库、数据表和连接都建立了,我们可以查看列表中的所有信息:


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

使用find_one()方法获取一条记录

在MongoDB中最基本的方法就是find_one()。这个方法返回一条符合条件的记录(或者None)。当你知道某条信息只有一个的时候,这个方法非常有用,或者返回第一条数据,这里我们使用这个方法获取第一条数据:


>>> posts.find_one()
{u'date': datetime.datetime(...), u'text': u'My first blog post!', u'_id': ObjectId('...'), u'author': u'Mike'

结果是我们之前插入的一条字典型的数据。

注意:返回结果中的“_id”是插入数据时自动添加的。

find_one()同时也提供了精确查找的功能,下面的示例是我们定位author为Mike的代码:


>>> posts.find_one({"author": "Mike"})
{u'date': datetime.datetime(...), u'text': u'My first blog post!', u'_id': ObjectId('...'), u'author': u'Mike'

如果我们把author换成另外一个,则不会返回结果:


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

使用ObjectId查询

我们也可以用“_id”来查询,下面是我们的示例:


>>> 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'

注意:ObjectId和转换为字符串的ObjectId是不一样的:


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

在web应用中一个很常见的现象就是从URI中获取ObjectId来查询后台记录。在使用这个之前需要把str类型转换成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)})

Unicode Strings注意事项

你可能会注意到我们的数据和存进去的数据有一些不一样,比如( u’Mike’ 而不是‘Mike’)。

MongoDB是使用BSON来存储数据。BSON是使用utf-8来编码的。所以PyMongo存储的str类型必须是utf-8的。(‘str’类型)也是要被支持的,因此Unicode类型(<‘unicode’类型>)需要先编码成utf-8,我们的示例中PythonShell显示的是u’Mike’而不是‘Mike’就是因为PyMongo解码了BSON的string变成Python的unicode string。
大量的插入数据

为了让查询更有意思,我们需要插入多一些数据。能够新增一条记录,我们也可以做到新增多条记录。使用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
new_post[1]有一个不同的地方,多了一个“tags”字段。而现在我们又多了一个字段,这就是我们说MongoDB非常schema-free(开放?)

查询一条以上的记录

我们使用find()方法来获取一条以上的记录。find()返回一组符合条件的记录,并且允许我们通过迭代的方式获取它们。例如,在post中我们可以迭代的获取所有查询的数据:


>>> 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还提供了许多种类的查询方式。例如我们查询数据的日期小于某一个日期,且按照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()来对author字段排序。

主键

增加一个主键能够帮助我们快速而准确的查询记录,也可以使我们存储的数据更加有用。在这个示例中,我们将会展示在一个已存在主键的表中新增一个主键:

首先,我们要新增一个主键:


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

注意,我们现在有两个主键了,一个是MongoDB自带的”_id“,另一个是我们新增的”user_id“。

现在,我们来新增一些用户信息:


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

我们新增的主键阻止我们新增一条已存在这个主键的记录。


>>> 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):
pymongo.errors.DuplicateKeyError: E11000 duplicate key error index: test_database.profiles.$user_id_1 dup key: { : 212 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值