使用PyMongo查询MongoDB数据库!

做者|LAKSHAY ARORA
编译|Flin
来源|analyticsvidhyapython

介绍

随着互联网的普及,咱们如今正之前所未有的速度生成数据。由于执行任何类型的分析都须要咱们从数据库中收集/查询必要的数据,因此选择正确的工具来查询数据变得相当重要。所以,咱们没法想象使用SQL来处理如此大量的数据,由于每一个查询的成本都很高。正则表达式

这正是MongoDB的用武之地。MongoDB是一个非结构化数据库,以文档形式存储数据。此外,MongoDB可以很是高效地处理大量数据,而且是使用最普遍的NoSQL数据库,由于它提供了丰富的查询语言以及对数据的灵活而快速的访问。sql

在本文中,咱们将看到有关如何使用PyMongo查询MongoDB数据库的多个示例。此外,咱们将看到如何使用比较运算符和逻辑运算符,正则表达式以及聚合管道的基础知识。mongodb

本文是MongoDB初学者教程(https://www.analyticsvidhya.com/blog/2020/02/mongodb-in-python-tutorial-for-beginners-using-pymongo) 的延续,其中咱们讨论了非结构化数据库,安装步骤和MongoDB基本操做的挑战。所以,若是你是MongoDB的初学者,我建议你先阅读该文章。数据库

目录

  1. 什么是PyMongo?express

  2. 安装步骤json

  3. 将数据插入数据库数组

  4. 查询数据库服务器

    1. 根据字段过滤
    2. 根据比较运算符进行过滤
    3. 基于逻辑运算符的过滤
    4. 经常使用表达
    5. 聚合管道
  5. 尾注框架

什么是PyMongo?

PyMongo是一个Python库,使咱们可以与MongoDB链接。此外,这是MongoDB和Python一块儿使用的最推荐的方法。

另外,咱们选择Python与MongoDB进行交互,由于它是数据科学中最经常使用且功能最强大的语言之一。PyMongo容许咱们使用相似于字典的语法来检索数据。

若是你是Python的初学者,我建议你参加此免费课程:Python入门。

安装步骤

安装PyMongo很是简单明了。在这里,我假设你已经安装了Python 3和MongoDB。如下命令将帮助你安装PyMongo:

pip3 install pymongo

将数据插入数据库

如今让咱们进行设置,而后再使用PyMongo查询MongoDB数据库。首先,咱们将数据插入数据库。如下步骤将为你提供帮助

  1. 导入库并链接到mongo客户端

在计算机上启动MongoDB服务器。我假设它正在localhost:27017运行文件。

让咱们开始导入一些咱们将要使用的库。默认状况下,MongoDB服务器在本地计算机上的端口27017上运行。而后,咱们将使用pymongo库链接到MongoDB客户端。

而后获取数据库sample_db的数据库实例。万一它不存在,MongoDB将为你建立一个。

# 导入所需的库
import pymongo
import pprint
import json
import warnings
warnings.filterwarnings('ignore')

# 链接到mongoclient
client = pymongo.MongoClient('mongodb://localhost:27017')

# 获取数据库
database = client['sample_db']
  1. 从JSON文件建立集合

咱们将使用在多个城市运营的一家送餐公司的数据。此外,他们在这些城​​市设有各类配送中心,用于向其顾客发送餐单。你能够在此处下载数据和代码。

  1. weekly_demand

    • id:每一个文档的惟一ID
    • week:周号
    • center_id:配送中心的惟一ID
    • meal_id:餐的惟一ID
    • checkout_price:最终价格,包括折扣,税金和送货费
    • base_price:餐的基本价格
    • emailer_for_promotion:发送电子邮件以促进进餐
    • homepage_featured:首页提供的餐点
    • num_orders:(目标)订单数
  2. meal_info

    • meal_id:餐的惟一ID
    • category:餐食类型(饮料/小吃/汤……)
    • cuisine:美食(印度/意大利/…)

而后,咱们将在sample_db数据库中建立两个集合:

# 建立每周需求收集
database.create_collection("weekly_demand")

# 建立餐食信息
database.create_collection("meal_info")

  1. 将数据插入集合

如今,咱们拥有的数据为JSON格式。而后,咱们将得到集合的实例,读取数据文件,并使用insert_many函数插入数据。

# 获取collection weekly_demand
weekly_demand_collection = database.get_collection("weekly_demand")

# 打开weekly_demand json文件
with open("weekly_demand.json") as f:
    file_data = json.load(f)
# 将数据插入集合
weekly_demand_collection.insert_many(file_data)

# 获取总数据点数    
weekly_demand_collection.find().count()
# >> 456548

# 获取收藏餐 
meal_info_collection = database.get_collection("meal_info")

# 打开meat_info json文件
with open("meal_info.json") as f:
    file_data = json.load(f)
    
# 将数据插入集合
meal_info_collection.insert_many(file_data)

# 获取总数据点数
meal_info_collection.find().count()
# >> 51

最后,在weekly_demand_collection中有456548个文档,在餐信息集合中有51个文档。如今,让咱们看一下每一个集合中的一个文档。

weekly_demand_collection

weekly_demand_collection.find_one()

膳食信息集

meal_info_collection.find_one()

如今,咱们的数据已准备就绪。让咱们继续查询该数据库。

查询数据库

咱们可使用带有查找功能的PyMonfo查询MongoDB数据库,以获取知足给定条件的全部结果,还可使用find_one函数,该函数将仅返回知足条件的一个结果。

如下是find和find_one的语法:

your_collection.find( {<< query >>} , { << fields>>} )

你可使用如下过滤技术查询数据库

  1. 根据字段过滤

例如,你有数百个字段,而你只想看到其中的几个。你能够经过将全部必填字段名称都设置为值1来实现此目的。例如,

weekly_demand_collection.find_one( {}, { "week": 1, "checkout_price" : 1})

另外一方面,若是只想从整个文档中丢弃一些字段,则能够将字段名称设置为等于0。所以,将仅排除那些字段。请注意,你不能使用1和0的组合来获取字段。要么所有为一,要么所有为零。

weekly_demand_collection.find_one( {}, {"num_orders" : 0, "meal_id" : 0})

  1. 过滤条件

如今,在本节中,咱们将在第一个大括号中提供一个条件,并在第二个中删除该字段。所以,它将返回center_id等于55且meal_id等于1885的第一个文档,而且还将丢弃字段_id和week。

weekly_demand_collection.find_one( {"center_id" : 55, "meal_id" : 1885}, {"_id" : 0, "week" : 0} )

  1. 根据比较运算符进行过滤

如下是MongoDB中的9个比较运算符。

名称 描述
$eq 它将匹配等于指定值的值。
$gt 它将匹配大于指定值的值。
$gte 它将匹配全部大于或等于指定值的值
$in 它将匹配数组中指定的任何值
$lt 它将匹配全部小于指定值的值
$lte 它将匹配全部小于或等于指定值的值
$ne 它将匹配全部不等于指定值的值
$nin 它将不匹配数组中指定的任何值

如下是使用这些比较运算符的一些示例

  1. 等于和不等于

咱们将找到center_id等于55且homepage_featured不等于0的全部文档。因为咱们将使用find函数,所以它将返回该命令的游标。此外,使用for循环遍历查询结果。

result_1 = weekly_demand_collection.find({
    "center_id" : { "$eq" : 55},
    "homepage_featured" : { "$ne" : 0}
})

for i in result_1:
    print(i)

  1. 在列表中和不在列表中

例如,你须要将一个元素与多个元素匹配。在这种状况下,咱们可使用$ in 运算符,而不是屡次使用 $eq运算符。咱们将尝试找出center_id为24或11的全部文档。

result_2 = weekly_demand_collection.find({
    "center_id" : { "$in" : [ 24, 11] }
})

for i in result_2:
    print(i)

而后,咱们找到全部在指定列表中不存在center_id的文档。如下查询将返回center_id不是24也不是11的全部文档。

result_3 = weekly_demand_collection.find({
    "center_id" : { "$nin" : [ 24, 11] }
})

for i in result_3:
    print(i)

  1. 小于和大于

如今,让咱们查找center_id为55而且checkout_price大于100且小于200的全部文档。为此,请使用如下语法

result_4 = weekly_demand_collection.find({
    "center_id" : 55,
    "checkout_price" : { "$lt" : 200, "$gt" : 100}
})

for i in result_4:
    print(i)

  1. 基于逻辑运算符的过滤器
名称 描述
$and 它将查询语句与逻辑链接起来,AND返回同时符合这两个条件的全部文档。
$not 它将反转查询的结果,并返回与查询表达式不匹配的文档。
$nor 它将使用逻辑将查询子句链接起来,NOR返回全部与子句不匹配的文档。
$or 它将使用逻辑将查询子句链接起来,OR返回匹配任一子句条件的全部文档。

如下示例说明了逻辑运算符的用法-

  1. AND运算符

下面的查询将返回center_id等于11,餐号不等于1778的文档。AND运算符的子查询将出如今列表中。

result_5 = weekly_demand_collection.find({
    "$and" : [{
                 "center_id" : { "$eq" : 11}
              },
              {
                   "meal_id" : { "$ne" : 1778}
              }]
})

for i in result_5:
    print(i)

  1. 或运算符
    如下查询将返回center_id等于11或餐ID为1207或2707的全部文档。此外,or运算符的子查询将位于列表内。
result_6 = weekly_demand_collection.find({
    "$or" : [{
                 "center_id" : { "$eq" : 11}
              },
              {
                   "meal_id" : { "$in" : [1207, 2707]}
              }]
})

for i in result_6:
    print(i)

  1. 用正则表达式过滤

当你有文本字段而且要搜索具备特定模式的文档时,正则表达式很是有用。若是你想了解有关正则表达式的更多信息,我强烈建议你阅读本文:Python正则表达式初学者教程。

它能够与运算符 $regex 一块儿使用,而且咱们能够为运算符提供值,使regex模式变为matc。咱们将在该查询中使用餐信息集,而后找到在美食字段中以C开头的文档。

result_7 = meal_info_collection.find({
    "cuisine" : { "$regex" : "^C" }
})

for i in result_7:
    print(i)

让咱们再来看一个正则表达式的例子。咱们将查找全部类别以“ S”开头且以“ ian ” 结尾的全部文档。

result_8 = meal_info_collection.find({
    "$and" : [
        { 
            "category" : {
            "$regex" : "^S"
        }},
        {
            "cuisine" : {
                "$regex" : "ian$"
        }}
    ]
})

for i in result_8:
    print(i)

  1. 聚合管道

MongoDB的聚合管道提供了一个框架,能够对数据集执行一系列数据转换。如下是其语法:

your_collection.aggregate( [ { <stage1> }, { <stage2> },.. ] )

第一个阶段将完整的文档集做为输入,而后每一个随后的阶段都将上一个转换的结果集做为下一个阶段的输入并产生输出。

MongoDB汇总中大约有10种转换可用,在本文中咱们将看到$ match和$ group。咱们将在即将发表的MongoDB文章中详细讨论每一个转换。

例如,在第一阶段,咱们将匹配center_id等于11的文档,在下一阶段,它将对center_id等于11的文档数量进行计数。请注意,咱们已经为$count运算符分配了一个值,该值等于第二阶段中的total_rows,这是咱们但愿在输出中显示的字段的名称。

result_9 = weekly_demand_collection.aggregate([
    ## stage 1
    {
        "$match" : 
                 {"center_id" : {"$eq" : 11 } }
    },
    ## stage 2
    {
        "$count" : "total_rows"
    }
])

for i in result_9:
    print(i)

如今,让咱们再举一个例子,第一个阶段与以前相同,即center_id等于11,在第二个阶段中,咱们要计算center_id 11的字段num_orders的平均值和center_id 11的惟一meal_ids。

result_10 = weekly_demand_collection.aggregate([
    ## stage 1
    {
        "$match" : 
                 {"center_id" : {"$eq" : 11 } }
    },
    ## stage 2
    {
        "$group" : { "_id" : 0 ,
                     "average_num_orders": { "$avg" : "$num_orders"},
                     "unique_meal_id" : {"$addToSet" : "$meal_id"}} 
    }
])

for i in result_10:
    print(i)

尾注

现在, 数据量之大使人难以置信,所以有必要找到更好的替代方法来查询数据。总而言之,在本文中,咱们学习了如何使用PyMongo查询MongoDB数据库。此外,咱们了解了如何根据所需状况应用各类过滤器。

若是你想了解有关查询数据的更多信息,我建议你学习如下课程 —— 数据科学的结构化查询语言(SQL)

在接下来的文章中,咱们将详细讨论聚合管道。

感谢阅读!

原文连接:https://www.analyticsvidhya.com/blog/2020/08/query-a-mongodb-database-using-pymongo/

欢迎关注磐创AI博客站:
http://panchuang.net/

sklearn机器学习中文官方文档:
http://sklearn123.com/

欢迎关注磐创博客资源汇总站:
http://docs.panchuang.net/

相关文章
相关标签/搜索