pymongo模块详解(含官方文档翻译)
发布日期:2021-05-07 14:32:55 浏览次数:15 分类:技术文章

本文共 5048 字,大约阅读时间需要 16 分钟。

  • pymongo支持MongoDB 2.6, 3.0, 3.2, 3.4, 3.6 and 4.0.

    1. 建立与MongoClient的连接

      使用PyMongo的第一步是创建一个MongoClient来运行mongod实例。很简单

      from pymongo import MongoClientclient = MongoClient()

      上述代码采用默认host和port,我们也可以制定host和port,例如:

      client = MongoClient('localhost', 27017)

      或者采用MongoDB URL格式:

      client = MongoClient('mongodb://localhost:27017/')
    2. 获取一个数据库Database

      一个MongoDB实例可以支持多种独立数据库,当使用pymongo你可以用针对MongoClient实例采用属性风格连接到数据库:

      db = client.test_database

      如果你的数据库名字是这样的(例如test-database),导致无法采用属性方式连接,可以采用字典方式连接:

      db = client['test-database']
    3. 获取一个连接Collection

      Collection是存储在MongoDB中的一组文档,可以粗略的理解为关系型数据库中的table,在pymongo中实现连接方式与获取数据库一样:

      collection = db.test_collection# orcollection = db['test-collection']

      MongoDB中关于collectionsdatabase有个重要特点:他们都是lazily创建的,上述所有命令都不会对服务器产生实际操作。

      只有在第一个document被嵌入后,Collectionsdatabases才会被创建。

    4. 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类型。

    5. 插入一个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()
    6. 查询query

      1. 用 获取一个单独的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’,没有结果。

      2. 通过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)})
      3. 查询多个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)
      4. 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排序。

    7. 关于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字符串,而非标准字符串。

      .

    8. 批量插入

      为了让查询变得更有趣,让我们插入更多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)
    9. 计数Counting

      如果我们知识想要知道符合查询条件的结果一共有多少,可以采用count_documents()操作,而不用全部查出来。

      posts.count_documents({       })

      或者只计算那些福特特定查询条件的:

      posts.count_documents({       'author':'Mike'})
    10. 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 }
上一篇:Mongo与robomongo
下一篇:什么是CTP程序化交易:系统入门

发表评论

最新留言

很好
[***.229.124.182]2025年03月24日 04时13分32秒