mongodb学习笔记

作者: xiaogp | 来源:发表于2020-06-18 19:21 被阅读0次

mongodb安装

# mongodb在ubuntu安装
sudo apt install mongodb

# 查看mongodb状态
systemctl status mongodb

命令行客户端操作mongodb

启动mongodb shell
mongo

登录指定host和port的mongo
mongo --host 192.168.61.240 --port 27017

查看所有的数据库
show dbs
显示当前数据库
db
db.getName()
切换数据库
use local
创建数据库
use gp

删除数据库
use gp
db.dropDatabase() # { "dropped" : "gp", "ok" : 1 }

创建集合
db.createCollection("runoob")

显示数据库下的所有集合(表)
show collections

删除集合的语法
db.collection.drop()

往集合中插入数据

db.col.insert({title: 'MongoDB 教程',
    description: 'MongoDB 是一个 Nosql 数据库',
    by: 'MongoDB中文网', 
    url: 'http://www.mongodb.org.cn', 
    tags: ['mongodb', 'database', 'NoSQL'],
    likes: 100  
})

查看已插入的数据
查看所有数据
db.col.find()

{ "_id" : ObjectId("5eeb0708f06c609838ae50c3"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "MongoDB中文网", "url" : "http://www.mongodb.org.cn", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }

将数据先定义为一个变量

document=({title: 'MongoDB 教程',
    description: 'MongoDB 是一个 Nosql 数据库', 
    by: 'Mongodb中文网',    
    url: 'http://www.mongodb.org.cn', 
    tags: ['mongodb', 'database', 'NoSQL'],  
    likes: 100  
})

在执行插入
db.col.insert(document)

查看一个表的一条数据,输出会格式化
db.col.findOne()

{
    "_id" : ObjectId("5eeb0f54c4f2cee2e99e1b3e"),
    "title" : "Mongodb",
    "description" : "MongoDB 是一个 Nosql 数据库",
    "by" : "Mongodb中文网",
    "url" : "http://www.mongodb.org.cn",
    "tags" : [
        "mongodb",
        "database",
        "NoSQL"
    ],
    "likes" : 100
}

条件查询
db.col.insert({title:"aa"})
db.col.find({title:"aa"})

使用条件操作符号
条件操作符需要单独给一个json格式
(1)范围查询, gt大于gte大于等于 lt小于lte小于等于
查看like大于100的数据
db.col.find({likes:{gt:100}}) db.col.find({likes:{gte:100}}) # 大于等于
db.col.find({likes:{lt:100}}) # 小于 db.col.find({likes:{lte:100}}) # 小于等于

(2)非查询$ne

查询entname不等于江苏永钢集团有限公司的

db.pira_ent_alias.find({"entname":{$ne:"江苏永钢集团有限公司"}})

(3)in查询in db.pira_ent_alias.find({"entname": {in:["昆山昌禾精密电子有限公司", "江苏永钢集团有限公司"]}})

(4) not in 查询 nin db.pira_ent_alias.find({"entname": {nin:["昆山昌禾精密电子有限公司", "江苏永钢集团有限公司"]}})

(5) 或查询 or db.pira_ent_alias.find({or: [{"entname":"昆山昌禾精密电子有限公司"},{"entname":"江苏永钢集团有限公司"}]})
一个查询条件家一个or组合条件, 相当于 A and (B or C)
db.pira_ent_alias.find({"shortname": "苏钢集团", $or: [{"entname":"昆山昌禾精密电子有限公司"},{"entname":"江苏永钢集团有限公司"}]})

(6) 模糊查询 $regex
查询包含“石油”的,相当于两边都是%%
db.pira_ent_alias.find({shortname: /石油/})
查询前缀是...的
db.pira_ent_alias.find({shortname: /^国家/})

多个查询条件
查询likes大于100的并且title是Spark 教程的
db.col.find({likes:{$gt:100},title:"Spark 教程"})

嵌套格式查询
插入嵌套数据
db.col.insert({title:"aaa",description:{aa:"1",bb:"2",cc:"3"}})
嵌套查询,用.代表内嵌查询
db.col.find({"description.aa":"1"})

insert和save,如果不指定_id字段, mongodb会自动生成ObjectId作为id
db.col.insert({title: "aa", _id:200})
db.col.insert({title: "bb", _id:200}) # 报错
db.col.save({title: "bb", _id:200}) # WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
db.col.save({title: "bb", _id:300}) # WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : 300 })

限制查询出的字段
db.pira_ent_alias.find({},{"shortname":1}) # 只显示shortname字段,第一个{}是查询条件保留
带有查询条件并且之选择title字段
db.col.find({"likes":{$gt:100}},{"title":1}) # 1表示需要这个字段,0表示不需要,除了_id其他都会不显示

{ "_id" : ObjectId("5eeb19dacf21729c60a0c3b5"), "title" : "Python 教程" }
{ "_id" : ObjectId("5eeb19e8cf21729c60a0c3b6"), "title" : "Spark 教程" }

设置不显示
db.col.find({"likes":{$gt:100}},{"title":1, "_id":0})

{ "title" : "Python 教程" }
{ "title" : "Spark 教程" }

对结果进行排序
db.col.find().sort({"likes": 1}) # 根据likes升序排列

limit, 查看前几个
db.col.find().sort({"likes": 1}).limit(3)

skip跳过记录
db.pira_ent_alias.find().skip(2) # 从第3个开始显示

命令结合使用,结合limit实现分页查询
db.pira_ent_alias.find().limit(2).skip(2)

也可以直接使用find函数中的参数实现分页查询
db.pira_ent_alias.find({}, {}, 1, 20) # 跳过前20个,展示1个, 前面两个{}保留,分别是查询条件和展示的列

mongodb的聚合
包括 count, distinct, group
查看某个集合下的文档数量
db.col.count()
count默认会忽略limit和skip参数,如果不忽略需要加上参数true,比如
db.pira_ent_alias.count() # 输入36
db.pira_ent_alias.find().limit(3).count() # 输入36
db.pira_ent_alias.find().limit(3).count(true) # 输入3

查看某一额字段的唯一值
db.pira_ent_alias.distinct("entname")
[
"中国国际金融股份有限公司",
"上海浦东发展银行股份有限公司",
"华为技术有限公司",
"江苏双联建设工程有限公司",
"苏州市宏大建设工程有限公司"
]
查看去重之后的总数
db.pira_ent_alias.distinct("entname").length # 输出5

删除文档/记录
use gp
移除 title 为 'MongoDB 教程'
db.col.remove({title:"MongoDB 教程"}) # WriteResult({ "nRemoved" : 3 })
只删除找到的第一个
db.col.remove({title:"MongoDB 教程"}, 1)

删除该集合下的所有文档
db.col.remove({})

更新文档
update条件更新
update用于更新已经存在的文档
先插入数据

db.col.insert({  
    title: 'Mongodb 教程',  
    description: 'MongoDB 是一个 Nosql 数据库',   
    by: 'Mongodb中文网',   
    url: 'http://www.mongodb.org.cn',   
    tags: ['mongodb', 'database', 'NoSQL'],  
    likes: 100  
})

通过update更新标题
db.col.update({title:'Mongodb 教程'},{set:{title:'MongoDB'}})set操作符替换掉指定字段的值
{ $set: { <field1>: <value1>, ... } }

{ "_id" : ObjectId("5eeb0d6cc4f2cee2e99e1b3c"), "title" : "MongoDB", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "Mongodb中文网", "url" : "http://www.mongodb.org.cn", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }

全部更新
以上语句只会修改第一条发现的文档,如果你要修改多条相同的文档,则需要设置 multi 参数为 true
db.col.update({title:"Mongodb 教程"}, {$set:{title:"Mongodb"}}, {multi:true})

创建索引
给col表的title列创建索引,1指定升序创建索引, -1指定倒序创建索引
db.col.ensureIndex({"title":1})
也可以对多个字段创建索引,相当于复合索引
db.col.ensureIndex({"title":1,"description":-1})
使创建索引的操作在后台完成
db.col.ensureIndex({"title":1,"description":-1}, {background: true})

查看索引
db.col.getIndexes()

一个新的数据库的索引
[
    {
        "v" : 2,
        "key" : {
            "_id" : 1  # 默认对_id列建立索引
        },
        "name" : "_id_",  # 名称是_id_
        "ns" : "gp.gp2"
    }
]

当mongodb 集合里面的数据过大时 创建索引很耗时,可以在放在后台运行, 可以指定索引名字, 默认的索引名是字段名_排序
db.userdatas.createIndex({"name":1},{"name":"myindex","background":true})

删除索引
db.col.dropIndex("title_1_description_-1") # 根据索引名字删除索引
db.pira_ent_alias.dropIndex("entname_1_formattedentname_1_shortname_1_score_1") # 组合索引也是通过组合的name删除

删除除了_id之外的所有索引
db.pira_ent_alias.dropIndexes()

查看是否使用了索引
db.pira_ent_alias.find({"entname":"江苏固德威电源科技股份有限公司", "score":{"$gte": 0}}).explain("executionStats")

没加索引

"executionStats" : {
    "executionSuccess" : true,
    "nReturned" : 10,  # 返回10条
    "executionTimeMillis" : 0,  # 执行时间
    "totalKeysExamined" : 0,  # 索引扫描条数
    "totalDocsExamined" : 186,  # 文档扫描条数
"executionStages" : {
        "stage" : "COLLSCAN",  # COLLSCAN 代表全表扫描

加索引

db.pira_ent_alias.createIndex({"entname":1, "score": -1})

重新执行一次explain

db.pira_ent_alias.find({"entname":"江苏固德威电源科技股份有限公司", "score":{"$gte": 0}}).explain("executionStats")

"executionStats" : {
"executionSuccess" : true,
"nReturned" : 10,
"executionTimeMillis" : 0, # 执行时间
"totalKeysExamined" : 10, # 索引扫描条数
"totalDocsExamined" : 10, # 文档扫描条数
"executionStages" : {
"stage" : "FETCH", # 根据索引去检索指定document

mongodb索引总结

1:创建索引时,1表示按升序存储,-1表示按降序存储。
2:可以创建复合索引,如果想用到复合索引,必须在查询条件中包含复合索引中的前N个索引列
3: 如果查询条件中的键值顺序和复合索引中的创建顺序不一致的话,MongoDB可以智能的帮助我们调整该顺序,以便使复合索引可以为查询所用。
4: 可以为内嵌文档创建索引,其规则和普通文档创建索引是一样的。
5: 一次查询中只能使用一个索引,or特殊,可以在每个分支条件上使用一个索引。 6:where,exists不能使用索引,还有一些低效率的操作符,比如:ne,not,nin等。
7: 设计多个字段的索引时,应该尽量将用于精确匹配的字段放在索引的前面。

Python操作mongodb

安装pymongo
pip install pymongo

创建一个客户端对象

from pymongo import MongoClient
client = MongoClient()
# 连接默认的host和port
client = MongoClient('localhost', 27017)
# 或者使用url风格进行连接
client = MongoClient('mongodb://localhost:27017/')

查看所有数据库

client.database_names()
['admin', 'config', 'gp', 'local', 'test']

获得数据库

使用属性方式
db = client.gp
# 使用字典方式
db = client['gp']

获得集合

collection = db.col
collection = db['col']

insert_one插入文档

import datetime
# 可以直接在字典中使用python的数据类型,可以自动被转化为BSON
post = {"author": "Mike", "text": "My first blog post!", "tags": ["mongodb", "python", "pymongo"], "date": datetime.datetime.utcnow()}

插入数据
posts = db.posts  # 指定当前数据库下的posts集合(表)
post_id = posts.insert_one(post).inserted_id

在mongo客户端查看数据
use gp
db.posts.find()
{ "_id" : ObjectId("5eeb23b26cbc10f88476d748"), "author" : "Mike", "text" : "My first blog post!", "tags" : [ "mongodb", "python", "pymongo" ], "date" : ISODate("2020-06-18T08:16:30.490Z") }

查看当前数据库下的所有集合

db.list_collection_names()
['gp2', 'runoob', 'posts', 'col']

查看单条数据find_one

posts.find_one()
{'_id': ObjectId('5eeb23b26cbc10f88476d748'),
 'author': 'Mike',
 'text': 'My first blog post!',
 'tags': ['mongodb', 'python', 'pymongo'],
 'date': datetime.datetime(2020, 6, 18, 8, 16, 30, 490000)}

带有查询条件查看单条数据

cols = db.col
cols.find_one({"title":"Mongodb"})

限制返回的列

col.find_one({},{"entname":True, "formattedentname": True})  # 第二个字段限制返回字段

模糊查询

# 某些特殊字符前面要加\\转义
# 查询包含,相当于两边都是%%
res = col.find({"shortname": {"$regex": "\\*ST"}})
# 查询前缀,以...开头
res = col.find({"shortname": {"$regex": "^\\*ST"}})

根据ObjectId进行查询

import bson
cols.find_one({"_id": bson.objectid.ObjectId('5eeb0f54c4f2cee2e99e1b3e')})
{'_id': ObjectId('5eeb0f54c4f2cee2e99e1b3e'),
 'title': 'Mongodb',
 'description': 'MongoDB 是一个 Nosql 数据库',
 'by': 'Mongodb中文网',
 'url': 'http://www.mongodb.org.cn',
 'tags': ['mongodb', 'database', 'NoSQL'],
 'likes': 100.0}

批量插入数据

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('5eeb27f56cbc10f88476d749'), ObjectId('5eeb27f56cbc10f88476d74a')]

获取多条数据

for post in posts.find():
    print(post)

增加查询条件做多条数据查询
for post in posts.find({"author": "Mike"}):
    print(post)

查看某个集合下文档数

posts.count_documents({})

# 也可以带有条件查询
posts.count_documents({"author": "Mike"})

排序
list(col.find({}).sort("entname")) # 默认升序
col.find({}).sort([("entname", -1)]) # 降序
col.find({}).sort([("entname", -1),("shortname", 1)]) # 多个排序条件

范围查询

d = datetime.datetime(2009, 11, 12, 12)
for post in posts.find({"date": {"$lt": d}}).sort("author"):  # python的时间数据类型可以直接比较
   print(post)

增加索引

result = db.posts.create_index([('date', pymongo.ASCENDING)], unique=True)
sorted(list(db.posts.index_information()))  # ['_id_', 'date_1']

批量插入,有就更新,没有就插入
ReplaceOne和UpdateOne的区别, ReplaceOne只能修改整个文档, UpdateOne可以只修改字段, 两者都是以一个条件作为修改条件

from pymongo import InsertOne, DeleteOne, ReplaceOne


data_list = [
    {"_id": get_md5("北京海国鑫泰投资控股中心" + "," + "海国鑫泰"), 
                               "text": "北京海国鑫泰投资控股中心" + "," + "海国鑫泰", 
                               "score": 0.8304597701149425, 
                               "updatedate": datetime.datetime.today().strftime("%Y-%m-%d %H:%M:%S")},
    {"_id": get_md5("北京海国鑫泰投资控股中心" + "," + "海国鑫泰"), 
                               "text": "北京海国鑫泰投资控股中心" + "," + "海国鑫泰", 
                               "score": 0, 
                               "updatedate": datetime.datetime.today().strftime("%Y-%m-%d %H:%M:%S")},
    {"_id": get_md5("兴证证券资产管理有限公司" + "," + "兴证资管"), 
                               "text": "兴证证券资产管理有限公司" + "," + "兴证资管", 
                               "score": 0.9833333333333333, 
                               "updatedate": datetime.datetime.today().strftime("%Y-%m-%d %H:%M:%S")}
    ]


def save_data(collection, data_list):
    query = []
    for data in data_list:
        query.append(ReplaceOne({'_id': data["_id"]}, data, upsert=True))
 
    if len(query) > 0:
        res = collection.bulk_write(query) 

save_data(db.company_synonym, data_list)

linux下mongo可视化客户端 Robo 3T

下载地址
https://robomongo.org/download
解压之后运行studio-3t-linux-x64.sh,直接下一步

studio1.png
使用条件查询
studio2.png

相关文章

网友评论

    本文标题:mongodb学习笔记

    本文链接:https://www.haomeiwen.com/subject/orluxktx.html