MongoDB(python处理及优化)

一、连接mongodb数据库

import pymongo


myclient = pymongo.MongoClient("mongodb://localhost:27017/")
# mydb = myclient["runoobdb"]
mydb = myclient.get_database("runoobdb")
# mycol = mydb["sites"]
mycol = mydb.get_collection("sites")
mycol2 = mydb["sites2"]
# dblist = myclient.list_database_names()
# print(dblist)
table_list = mydb.list_collections()
for i in table_list:
    print(i)

二、插入数据

mydict = {"name": "RUm", "alexa": "10222", "url": "https://www.runoob2.com"}

x = mycol.insert_one(mydict)
print(x.inserted_id)


for i in range(6, 100000):
  insert_dict = {"_id": i, "name": "测试" + str(i), "address": "test" + str(i)}
  mycol2.insert_one(insert_dict)
mylist = [
  {"name": "Taobao", "alexa": "100", "url": "https://www.taobao.com"},
  {"name": "QQ", "alexa": "101", "url": "https://www.qq.com"},
  {"name": "Facebook", "alexa": "10", "url": "https://www.facebook.com"},
  {"name": "知乎", "alexa": "103", "url": "https://www.zhihu.com"},
  {"name": "Github", "alexa": "109", "url": "https://www.github.com"}
]

x = mycol.insert_many(mylist)
print(x)

# 指定id插入
mylist = [
  {"_id": 1, "name": "RUNOOB", "cn_name": "菜鸟教程"},
  {"_id": 2, "name": "Google", "address": "Google 搜索"},
  {"_id": 3, "name": "Facebook", "address": "脸书"},
  {"_id": 4, "name": "Taobao", "address": "淘宝"},
  {"_id": 5, "name": "Zhihu", "address": "知乎"}
]

x = mycol2.insert_many(mylist)

# 输出插入的所有文档对应的 _id 值
print(x.inserted_ids)

三、删除操作

# 删除集合
mycol.drop()

myquery = {"name": "Zhihu"}
mycol.delete_one(myquery)

# 删除所有 name 字段中以 F 开头的文档
myquery = {"name": {"$regex": "^F"}}
mycol.delete_many(myquery)

# 删除集合中所有数据
mycol.delete_many({})

四、更新数据

# 指定条件更新,没有该字段就新增
myquery = {"name": "知乎"}
new_value = {"$set": {"aaa": "11111"}}
mycol.update_one(myquery, new_value)

# 以下实例将查找所有以 R 开头的 name 字段,并将匹配到所有记录的 ccc 字段修改为 11111:
myquery = {"name": {"$regex": "^R"}}
new_value = {"$set": {"ccc": "11111"}}
mycol.update_many(myquery, new_value)

五、查询数据

# 查询集合第一条数据
# 查询语句的处理方式
a = mycol2.find({"_id": {"$regex": "^.1"}}).sort("_id", -1).explain().values()
for i in a:
    print(i)

a = mycol.find_one()
print(a)
# 查询所有
for x in mycol.find():
  print(x)

# 升序排序
print('\n')
for x in mycol.find().sort("alexa"):
  print(x)

# 降序排序
print('\n')
for x in mycol.find().sort("alexa", -1):
  print(x)

# in条件,not in是nin
mycol2.find({"_id": {"$nin": [1, 2, 3]}})
for x in mycol2.find({"_id": {"$in": [1, 2, 3]}}):
  print(x)

# 正则:末尾为1和大于
x = mycol2.find({"name": {"$regex": "1$", "$gt": "测试9971"}})
for i in x:
  print(i)

# mycol2.aggregate([{$group : {_id : "$djgkyy_sys", num_w : {$sum : 1}}}])
# 分组并排序,按工况类别分组统计,并降序。
# mycol2.aggregate([{$group : {"_id" : "$djgkyy_sys", "num_w" : {$sum : 1}}},{$sort:{"num_w":-1}}])
# 去重: collection.distinct(‘jh’)
# 组合(and)查询
# mycol2.find({'djgkyy_sys':{$ne:null},'cjsj_ny':{$gt:'201501'}}).count()
# 通过match过滤后分组
# mycol2.aggregate([{"$match":{'cjsj_ny':{"$gt":'201501'}}},{"$group" : {"_id" : "$djgkyy_sys", "num_w" : {"$sum" : 1}}},{"$sort":{"num_w":-1}}])

# 判断某个数据是否存在,存在为1,不存在为0
# aa = mycol2.count_documents({"$and": [{"name": '测试1111'}, {"address": 'test1111'}]})
# print('aa', aa)

# 判断某个数据是否存在,存在为1,不存在为0
# aa = mycol2.count_documents({"$and": [{"name": '测试1111'}, {"address": 'test1111'}]})
# print('aa', aa)

六、创建索引

mycol2.create_index([("name", pymongo.DESCENDING)], background=True)
# 创建单个索引
mycol2.create_index('name', name='device_phone_alive_tbl_index')
# 创建复合索引(唯一索引)
mycol2.create_index([("name", 1), ("address", 1)], unique=True, name='device_phone_tbl_index')
# 删除索引,如果没有该索引会报错
mycol2.drop_index('name_-1')

# 强行使用索引查询
a = mycol2.find({"name": {"$regex": "1$", "$gt": "测试9971"}}).hint("device_phone_alive_tbl_index").sort('name')
for i in a:
    print(i)

aa = mycol2.list_indexes()
for i in aa:
    print(i)

七、优化

1、数据库设计的时候

一个集合的数据嵌入到另一个集合,选择部分嵌入,譬如一本书,可能有很多作者,然后这些作者可能会有很多书的时候;
假如姓名和籍贯用的多,可以选择将这两个字段和id一起存入,而不是只存id或者是全部的字段存入到里面;
假如是只存id或者是存全部字段的,只存id的,取数据不好取;存全部字段的,修改数据不好修改。

2、建索引

数据量越大,在查询上百万千万亿的数据的时候,在没有索引的情况下,可能是几秒甚至是更久的时间
这种情况下,最好给经常查询的数据加上你所需要的索引,这时候你的查询速度可能会变得非常的快

何时不应该使用索引:提取较小的子数据集时,索引非常有效(所以才有了分页)。也有一些查询不使用索引会更快。结果集在原集合中所占的比例越大,查询效率越慢。
因为使用索引需要进行两次查找:一次查找索引条目,一次根据索引指针去查找相应的文档。而全表扫描只需要进行一次查询。在最坏的情况,使用索引进行查找次数会是全表扫描的两倍。效率会明显比全表扫描低。

一般来说,如果查询需要返回集合内30%的文档(或者更多),那就应该测试全表扫描和走索引查询那个速度比较快。这个数字也会在2%~60%之间进行波动。
这个时候可以使用hint({“$natural”:true})强制查询走全表扫描。

3、exlpain来判断查询语句的执行情况,来进行调优

millis:操作所花时间,毫秒;如果millis的值较大,就需要进行优化

4、MongoDB中低效率的操作符,数据量大表的慎用

w h e r e " 和 " where"和" where""exists”:这两个操作符,完全不能使用索引。

n e " : 通常来说取反的效率比较低。 " ne":通常来说取反的效率比较低。" ne":通常来说取反的效率比较低。"ne"查询可以使用索引,但并不是很有效。
因为他必须查看所有的索引条目,而不是”$ne"指定的条目,这个时候他就不得不扫描整个索引。

" n o t " : 有时候能够使用索引,但是他通常并不知道要如何使用索引。所以大多数情况 " not":有时候能够使用索引,但是他通常并不知道要如何使用索引。所以大多数情况" not":有时候能够使用索引,但是他通常并不知道要如何使用索引。所以大多数情况"not"会退化为全表扫描。
“$nin”:这个操作符总是会全表扫描

5、OR查询

" o r " 实际上是执行两次查询然后将结果合并 M o n g o D B 在一次查询中只能使用一个索引 ( 至少我现在用的 2.6 是这样的 ) ,如果你在 " x " : 1 上有一个索引,在 " y " : 1 上也有一个索引,在 " x " : 1 , " y " : 1 上执行查询时, M o n g o D B 只会使用其中一个索引,而不是两个一起使用。 " or"实际上是执行两次查询然后将结果合并 MongoDB在一次查询中只能使用一个索引(至少我现在用的2.6是这样的),如果你在{"x":1}上有一个索引,在{"y":1}上也有一个索引,在{"x":1,"y":1}上执行查询时, MongoDB只会使用其中一个索引,而不是两个一起使用。" or"实际上是执行两次查询然后将结果合并MongoDB在一次查询中只能使用一个索引(至少我现在用的2.6是这样的),如果你在"x":1上有一个索引,在"y":1上也有一个索引,在"x":1,"y":1上执行查询时,MongoDB只会使用其中一个索引,而不是两个一起使用。"or"是一个例外," o r " 可以对每个字句都使用索引,因为 " or"可以对每个字句都使用索引,因为" or"可以对每个字句都使用索引,因为"or"实际上是执行两次查询然后将结果合并。
通常来说,使用or查询多次在合并结果,不如单次查询的效率高,对于单个字段,应该尽可能使用$in。

6、MongoDB的查询优化器

MongoDB的查询优化器与其他数据库的稍微不同。基本来说,如果一个索引能够精确匹配一个查询,那么查询优化器就会使用这个索引,如果不能精确匹配,
可能会有几个索引都适合你的查询。那MongoDB是怎样选择的呢?答:MongoDB的查询计划会将多个索引并行的去执行,最早返回100个结果的就是胜者,其他查询计划都会被终止。
这个查询计划会被缓冲,接下来的这个查询都会使用他,下面几种情况会重新计划;
最初的计划评估之后集合发生了比较大的数据波动,查询优化器就会重新挑选可行的查询计划。
建立索引时。
每执行1000次查询之后,查询优化器就会重新评估查询计划

  • 76
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值