MongoDB – это база данных NoSQL. Эта статья в основном знакомит с некоторыми основными понятиями и операциями в MongoDB, а также с установкой и использованием инструментов визуализации.
Автор: необузданная красотка
Время чтения около 20 минут+
1 Введение в MongoDB
MongoDB — это база данных NoSQL, в которой хранятся объекты данных, состоящие из пар ключ-значение. Все данные, хранящиеся в коллекциях MongoDB, имеют формат BSON. BSON — это формат хранения в двоичной форме, аналогичный JSON, сокращение от Binary JSON. Следующим образом:
{
"_id" : ObjectId("5c89f787ca6e4e3ac1ecabkk"),
"_plat" : "test_plat0",
"update_time" : ISODate("2019-06-03T15:00:42.142Z"),
"create_time" : ISODate("2019-03-14T14:41:11.217Z"),
"creator" : "test_user",
"admin" : [
"admin1",
"admin2"
],
"ops" : [
"ops1"
],
"labels" : {
"department" : "departmentA",
"main_class" : "mainClassA"
}
}
Ниже представлены некоторые основные понятия MongoDB по сравнению с реляционными базами данных:
Терминология реляционных баз данных | Терминология MongoDB | иллюстрировать |
---|---|---|
database | database | база данных |
table | collection | Таблица/коллекция базы данных |
row | document | строка записи/документ |
column | field | поле данных/домен |
index | index | показатель |
primary key | primary key | Первичный ключ, Mongodb автоматически устанавливает поле _id в качестве первичного ключа |
MongoDB можно лучше понять с помощью следующих сравнений:
id | Имя | возраст | Пол |
---|---|---|---|
1 | Чжан Сан | 23 | мужчина |
2 | Ли Си | 21 | мужчина |
Форма данных приведенных выше реляционных данных в MongoDB:
{
"_id" : ObjectId("5c89f787ca6e4e3ac1ehhb23"),
"姓名" : "张三",
"年龄" : 23,
"性别" : "男"
}
{
"_id" : ObjectId("5c89f787ca6e4e3ac1ehhb24"),
"姓名" : "李四",
"年龄" : 21,
"性别" : "男"
}
2 основные операции MongoDB
В этом разделе в основном представлена работа с MongoDB через командную строку, на примере установки MongoDB на CentOS.
2.1 Основные операции, такие как db и коллекции
Операции просмотра, создания и удаления БД, а также просмотра, создания и удаления коллекций следующие:
[root] mongo #命令行输入mongo进入MongoDB命令交互模式
> show dbs #列出已有db
> use my_db #如果my_db存在,则切换到my_db,如果不存在,则创建之
> db #显示当前db
> show dbs #发现列表里面没有my_db,因为此时db里面没有实际数据或者集合哦
> db.createCollection("my_col") #创建集合my_col
> db.my_col_new.insert({"name":"测试一下"}) #往集合my_col_new里面插入一条数据,如果集合不存在,会自动创建
> show collections #列出改db下面所有的集合
> show tables #功能跟show collections是一样的哦
> db.my_col.drop() #删除集合my_col
> db.dropDatabase() #删除当前数据库,执行之前用db命令确认一下当前数据库是不是你要删除的这个哦
2.2 Вставка данных
Существует 4 метода вставки данных: insert, insertOne, insertMany, save, которые подробно описаны ниже на примерах.
> db.my_col.insert({"name":"xiaoming"}) #insert可以插入一条数据
> db.my_col.insert([{"name":"xiaoming"},{"name":"test_user"}]) #insert也可以插入多条数据
> db.my_col.insertOne({"name":"xiaoming"}) #insertOne只能插入一条数据
> db.my_col.insertMany([{"name":"xiaoming"}]) #insertMany可以插入一条或多条数据,但是必须以列表(list)的形式组织数据
> db.my_col.save([{"name":"xiaoming"},{"name":"test_user"}]) #如果不指定_id,save的功能与insert一样
> db.my_col.save({"_id":ObjectId("5d07461141623d5db6cd4d43"),"name":"xiaoming"}) #如果指定_id,mongodb就不为该条记录自动生成_id了,只有save可以指定_id,insert、insertOne、insertMany都不可以
2.3 Модификация данных
Есть два способа изменить данные: обновить и сохранить, которые подробно описаны ниже.
2.3.1 update
Во-первых, взгляните на синтаксис формата обновления, обратите особое внимание на значения некоторых необязательных параметров, которые напрямую повлияют на ваши результаты модификации:
db.collection.update(
<query>, #update的查询条件,类似sql update语句where后面的部分
<update>, #update的对象和一些更新的操作符等,也可以理解为sql update语句set后面的
{
upsert: <boolean>, #可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入
multi: <boolean>, #可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新
writeConcern: <document> #可选,抛出异常的级别
}
)
Предположим, что у ученика есть оценочный лист, подобный этому:
> db.my_col.insert([{"name":"xiaoming","class":"c++", "score":60},{"name":"xiaoming","class":"python", "score":95}])
> db.my_col.find().pretty()
{
"_id" : ObjectId("5d0751ef41623d5db6cd4d44"),
"name" : "xiaoming",
"class" : "c++",
"score" : 60
}
{
"_id" : ObjectId("5d0751ef41623d5db6cd4d46"),
"name" : "xiaoming",
"class" : "python",
"score" : 95
}
Одноклассник Сяомина обнаружил, что учитель неправильно записал ее оценку по курсу C++ и должен был изменить ее до 75 баллов:
> db.my_col.update({"_id":ObjectId("5d0751ef41623d5db6cd4d44")},{$set:{"score":75}})
Учитель обнаружил, что имя одноклассника Сяомина было неверным и его нужно исправить:
> db.my_col.update({"name":"xiaoming"},{$set:{"name":"xming"}}) #这样是不对的,只会修改一条记录
> db.my_col.update({"name":"xiaoming"},{$set:{"name":"xming"}},{multi:true}) #这样才对
Измените оценку курса Java xming на 95, если не найдено, вставьте запись
> db.my_col.update({"name":"xming", "class": "java"},{$set:{"score": 95}},true)
2.3.2 save
Метод сохранения заменяет существующий документ переданным документом. Формат синтаксиса следующий:
db.collection.save(
<document>, #文档数据
{
writeConcern: <document> #可选,抛出的异常级别
}
)
В качестве примера возьмем стенограмму ученика выше:
> db.my_col.save({
"_id" : ObjectId("5d0751ef41623d5db6cd4d44"), #指定_id,新的文档会将旧的文档覆盖
"name" : "xming",
"class" : "c++",
"score" : 80
})
2.4 Удаление данных
Для удаления данных можно использовать deleteOne, deleteMany и remove, которые подробно описаны ниже.
2.4.1 удалить один и удалить много
Способ применения следующий:
> db.my_col.deleteOne({"name":"xming"}) #删除xming的一条成绩记录
> db.my_col.deleteMany({"name":"xming"}) #删除xming的所有成绩记录
> db.my_col.deleteMany({}) #删除成绩表里面的所有内容
2.4.2 remove
Во-первых, давайте посмотрим на формат синтаксиса:
db.collection.remove(
<query>, #可选,查询条件
{
justOne: <boolean>, #可选,设置为true或者1,表示只删除一个文档,设置为false,表示删除所有匹配的文档,默认为false
writeConcern: <document> #可选,抛出异常的级别
}
)
Удалить все записи оценок для xming:
> db.col.remove({"name":"xming"})
> db.repairDatabase() #remove方法并不会真正释放空间,需要继续执行 db.repairDatabase() 来回收磁盘空间
> db.runCommand({ repairDatabase: 1 }) #与上一句等效,仍以执行一句即可
ps: удаление теперь устарело, и методы deleteOne и deleteMany официально рекомендуются.
2.5 Запрос данных
К методам запроса данных относятся findOne и find. Параметры у них одинаковые, но findOne возвращает только одни совпадающие данные, а find возвращает все совпадающие данные. Ниже в основном представлено использование find.
2.5.1 Условные операторы
действовать | написание sql запроса | написание запроса монго |
---|---|---|
равный | select * from my_col where score = 75; | db.my_col.find({"score": 75}).pretty() |
меньше, чем | select * from my_col where score < 75; | db.my_col.find({"score": {$lt: 75}}).pretty() |
меньше или равно | select * from my_col where score <= 75; | db.my_col.find({"score": {$lte: 75}}).pretty() |
больше, чем | select * from my_col where score > 75; | db.my_col.find({"score": {$gt: 75}}).pretty() |
больше или равно | select * from my_col where score >= 75; | db.my_col.find({"score": {$gte: 75}}).pretty() |
не равно | select * from my_col where score != 75; | db.my_col.find({"score": {$ne: 75}}).pretty() |
ps: довольно позволяет распечатывать результаты запроса в отформатированном json для удобства просмотра
2.5.2 Сортировка, ограничение и пропуск
Отображать оценки учащихся по курсу C++ в порядке возрастания оценок, показывая только учеников с 10-го по 20-е:
> db.my_col.find({"class": "c++"}).sort({"score": -1}).skip(9).limit(11).pretty()
#sort:1为升序,-1为降序,默认升序
#limit:显示多少条数据
#skip:跳过多少条数据
2.5.3 Запрос составного условия и, или
и: метод find может передавать несколько пар ключ-значение, и каждая пара ключ-значение отделяется запятой, то есть условие И обычного SQL
Запросите оценки студентов сяомин по курсу C++:
> db.my_col.find({"name": "xiaoming", "class": "c++"}).pretty()
Чтобы запросить записи оценок от 75 до 85:
> db.my_col.find({"score": {$gt: 75, $lt: 85}}).pretty()
or: Условный оператор MongoDB OR использует ключевое слово $or, и его синтаксис выглядит следующим образом:
> db.col.find(
{
$or: [
{key1: value1}, {key2:value2}
]
}
).pretty()
Чтобы проверить оценки за курс сяомин или чжансан:
> db.my_col.find({$or: [{"name": "xiaoming"}, {"name": "zhangsan"}]}).pretty()
и + или составной запрос:
Запросите оценки курсов сяомина по c++ или python:
> db.my_col.find({"name": "xiaoming", $or: [{"class": "c++"}, {"class": "python"}]}).pretty()
2.5.4 Включая, не включая нин, все все
Запросите результаты xiaoming, zhangsan и lisa:
> db.my_col.find({"name": {$in: ["xiaoming","zhangsan","lisa"]}}).pretty()
Запрос оценок других, кроме xiaoming, zhangsan и lisa:
> db.my_col.find({"name": {$nin: ["xiaoming","zhangsan","lisa"]}}).pretty()
in и nin просты для понимания, похожи на использование sql, все аналогично in, разница в том, что in нужно удовлетворять только одному значению в списке, а all нужно удовлетворять всем значениям в списке. Например, существует следующая учебная программа, в которой указаны курсы, которые проходит каждый студент:
> db.course.find().pretty()
{
"_id" : ObjectId("5d084f1541623d5db6cd4d4c"),
"name" : "xiaoming",
"course" : [
"c++",
"python",
"java"
]
}
{
"_id" : ObjectId("5d084f1c41623d5db6cd4d4d"),
"name" : "lisa",
"course" : [
"c++",
"python",
"java"
]
}
{
"_id" : ObjectId("5d084f4a41623d5db6cd4d4e"),
"name" : "tom",
"course" : [
"c++",
"python"
]
}
Нужно найти студентов, которые прошли курсы c++ и java:
> db.course.find({"course": {$all: ["c++", "java"]}}).pretty() # 用 all 操作符,表示需要满足 c++ 和 java 两项
2.5.5 Оценка того, существует ли поле существует
Например, есть следующая таблица, представляющая информацию о студентах:
> db.stu_info.find().pretty()
{
"_id" : ObjectId("5d08519a41623d5db6cd4d4f"),
"name" : "xiaoming",
"tel" : "138xxxxxxxx"
}
{
"_id" : ObjectId("5d08531641623d5db6cd4d50"),
"name" : "lisa"
}
{
"_id" : ObjectId("5d08542e41623d5db6cd4d51"),
"name" : "tom",
"tel" : null
}
Нужно найти студентов, у которых нет поля тел:
> db.stu_info.find({"tel": {$exists: false}}).pretty() #字段不存在就用false,存在就用true
2.5.6 Обработка нуля null
Взяв в качестве примера приведенную выше таблицу информации о студентах, найдите студентов, чей телефон пуст:
> db.stu_info.find({"tel": null}).pretty()
{
"_id" : ObjectId("5d08531641623d5db6cd4d50"),
"name" : "lisa"
}
{
"_id" : ObjectId("5d08542e41623d5db6cd4d51"),
"name" : "tom",
"tel" : null
}
В настоящее время поле tel не существует, а значение tel равно null. Если вы хотите найти только случай, когда значение tel равно null:
> db.stu_info.find({"tel": {$in:[null], $exists:true}}).pretty()
2.5.7 Режим работы по модулю
Например, чтобы найти данные, в которых оценки учащихся по модулю 10 равны 0 (т.е. 100, 90, 80... и т. д.):
> db.my_col.find({"score": {$mod: [10, 0]}}).pretty()
2.5.8 Регулярное регулярное выражение соответствия
Запросить оценки учеников, чьи имена начинаются с буквы:
> db.my_col.find({"name": {$regex: /^a.*/}})
2.5.9 Получение количества результатов запроса
Получите количество записей успеваемости учащихся:
> db.my_col.find().count()
Когда метод limit используется для ограничения количества возвращаемых записей, метод count по-прежнему возвращает общее количество записей по умолчанию. Если вы хотите вернуть количество записей после ограничения, используйте count(true) или count(non-zero):
> db.my_col.find().count()
4
> db.my_col.find().limit(1).count()
4
> db.my_col.find().limit(1).count(true)
1
2.5.10 distinct
Чтобы запросить список всех учащихся в ведомости оценок курса:
> db.my_col.distinct("name")
2.6 Совокупность
В MongoDB инфраструктура агрегирования может использоваться для преобразования и объединения документов в коллекции для выполнения некоторых сложных операций запросов. Платформа агрегации использует несколько компонентов для создания конвейера для обработки последовательности документов. Эти компоненты включают, но не ограничиваются:
оператор | значимость |
---|---|
$match | фильтр |
$project | Cast, выберите нужное поле или переименуйте поле |
$group | группировка |
$unwind | расколоть |
$sort | Сортировать |
$limit | Ограничить количество запросов |
$skip | пропустить несколько баров |
Когда нам нужно использовать несколько операторов для завершения агрегирования документов, мы можем передать условие массива, что также является распространенным использованием агрегата:
> db.my_col.aggregate([
{$match: {"name": "xiaoming"}}, #查找 xiaoming 同学的课程成绩
{$project: {"_id": 0}}, #不需要_id字段
{$sort: {"score": -1, "class": 1}}, #按分数降序排序;同样分数的,按课程名字升序排序
{$skip: 1}, #跳过一条数据
{$limit: 1} #只显示一条数据
])
$match используется для фильтрации набора документов, а затем для отфильтрованного подмножества документов могут быть выполнены агрегаты. «$match» может использовать все обычные операторы запросов («$gt», «$lt», «$in» и т. д.). Как правило, при реальном использовании «$match» следует размещать в начале конвейера настолько, насколько это возможно. Это имеет два преимущества: во-первых, нежелательные документы можно быстро отфильтровать, чтобы уменьшить нагрузку на конвейер; во-вторых, если перед приведением и группировкой выполняется "$match", запрос может использовать индекс.
$project может извлекать поля из вложенных документов и переименовывать поля. Например, чтобы найти оценки учащихся за курс, не отображайте поле _id, отображайте поля имени, курса, оценки и переименуйте поле имени в student_name:
> db.my_col.aggregate([
{$project: {"_id": 0, "student_name": "$name", "core": 1, "class": 1}}
])
Использование $sort, $skip и $limit легко понять, поэтому я не буду объяснять больше.
$group аналогична group by в sql и в основном используется для обработки данных, например, для подсчета общей оценки за курс каждого студента:
> db.my_col.aggregate([
{$group: {_id: "$name", total: {$sum: "$score"}}}
])
$sum можно заменить операторами $avg, $min, $max, которые представляют среднюю, минимальную и максимальную оценки соответственно.
$unwind может разделить каждое значение в массиве на отдельный документ, например следующую запись, которая записывает блог и следующие комментарии:
> db.blog.findOne().pretty()
{
"_id":ObjectId("5359f6f6ec7452081a7873d7"),
"title":"这是一篇博客",
"auth":"xiaoming",
"comments":[
{
"author":"lisa",
"date":ISODate("2019-01-01T17:52:04.148Z"),
"text":"Nice post"
},
{
"author":"tom",
"date":ISODate("2019-01-01T17:52:04.148Z"),
"text":"I agree"
}
]
}
Теперь, чтобы найти комментарии Лизы, вы можете использовать $unwind, чтобы разделить каждый комментарий на отдельный документ, а затем выполнить запрос на соответствие:
> db.blog.aggregate({"$unwind":"$comments"})
{
"results":
{
"_id":ObjectId("5359f6f6ec7452081a7873d7"),
"title":"这是一篇博客",
"author":"xiaoming",
"comments":{
"author":"lisa",
"date":ISODate("2019-01-01T17:52:04.148Z"),
"text":"Nice post"
}
},
{
"_id":ObjectId("5359f6f6ec7452081a7873d7"),
"title":"这是一篇博客",
"author":"xiaoming",
"comments":{
"author":"tom",
"date":ISODate("2019-01-01T17:52:04.148Z"),
"text":"I agree"
}
}
}
> db.blog.aggregate([
{"$unwind":"$comments"},
{"$match":{"comments.author":"lisa"}}
])
2.7 Указатель
Индексы обычно могут значительно повысить эффективность запросов.Без индексов MongoDB должна сканировать каждый файл в коллекции и выбирать те записи, которые удовлетворяют условиям запроса при чтении данных. Эффективность запроса сканирования всей коллекции очень низкая, особенно при обработке большого объема данных запрос может занимать десятки секунд или даже несколько минут, что очень фатально сказывается на производительности сайта. Индекс — это специальная структура данных, которая хранится в наборе данных, которые легко просматривать и читать.Индекс — это структура, которая сортирует значения одного или нескольких столбцов в таблице базы данных.
Основной синтаксис для создания индекса следующий:
db.collection.createIndex(
{key1: option1, key2: option2}, #key为要创建索引的字段,option为创建索引的方式:1 为升序,-1 为降序,可以对多个字段创建索引,称为复合索引
{
background: <boolean>, #可选,建索引过程会阻塞其它数据库操作,background 设置为 true 可指定以后台方式创建索引,默认值为 false
unique: <boolean> #可选,建立的索引是否唯一。指定为true创建唯一索引。默认值为false
name: <string> #可选,索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称
sparse: <boolean> #可选,对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档。默认值为 false
}
)
Создайте индекс в таблице оценок учащихся:
> db.my_col.createIndex({"score": 1}, {background: true}) #在后台创建
> db.my_col.getIndexes() #查看集合索引
> db.my_col.totalIndexSize() #查看集合索引大小
> db.my_col.dropIndex("索引名称") #删除集合指定索引
> db.my_col.dropIndexes() #删除集合所有索引
3 инструмента визуализации
MongoDB имеет кроссплатформенный инструмент визуализации Robo 3T, который очень прост и удобен в использовании.
Скачать и установить адрес:robomongo.org/download
После успешной загрузки и установки нажмите «Файл» → «Подключиться», появится следующее небольшое окно, а затем нажмите «Создать», чтобы создать новую конфигурацию:
Заполните правильный адрес и порт и сохраните его.
После установки в соответствии с приведенным выше руководством, если вы не можете подключиться к настроенной MongoDB, за исключением сетевых причин, это может быть связано с тем, что адрес прослушивания конфигурации службы БД — 127.0.0.1, который необходимо изменить на 0.0.0.0.
Дважды щелкните настроенное соединение, чтобы войти в интерактивный интерфейс, как показано на следующем рисунке.Слева — информация о базе данных и коллекции, а справа — результат запроса. Вы можете ввести команду запроса в командной строке и нажать «Выполнить», чтобы выполнить такие операции, как фильтрация.
Вы также можете напрямую щелкнуть правой кнопкой мыши документ для просмотра, редактирования и других операций, что очень удобно.
4 Справочные документы
Учебник для новичков в MongoDB:ооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооо.
Расширенный запрос MongoDB:Стать.Hubeiwiz.com/card/from/543no…
Агрегация MongoDB:Стать.Hubeiwiz.com/card/from/5481…
Официальная документация MongoDB:docs.MongoDB.com/manual/int R…
Руководство по роботу 3T:блог woo woo woo.cn на.com/Tugenhua070…> MongoDB — это база данных NoSQL.Эта статья в основном знакомит с некоторыми основными понятиями и операциями в MongoDB, а также с установкой и использованием инструментов визуализации.
Подпишитесь на официальный аккаунт [IVWEB Community], чтобы получать свежие статьи каждую неделю, ведущие к вершине жизни!