Tianhe Gao

MongoDB

NoSQL 的面向文档的数据库。MongoDB 的数据存储的格式为 BSON(a binary version of JSON)。

MongoDB CRUD 概念

MongoDB 数据类型:Null, Boolean, Number, String, Date, Regular Expression, Array, Embeded Document, Object ID

比较查询操作符:

  • $eq Equal
  • $lt less than
  • $lte less than or equal
  • $gt greater than
  • $gte greater than or equal
  • $ne not equal
  • $in in
  • $nin not in

逻辑查询操作符:

  • $and
  • $or
  • $not
  • $nor

元素查询操作符:

  • $exists
  • $type

数组查询操作符:

  • $size
  • $all
  • $elemMatch

分类与限制:

  • sort()
  • limit()

聚合管道:

  • $avg
  • $count
  • $sum
  • $max
  • $min

索引:

  • getIndexes()
  • explain()
  • createIndex()

关系型数据库和 MongoDB 的对比

重要官方文档

数据表格式:

img/sql-nosql.jpg
数据表格式

关键词:

img/sql-nosql-2.png
关键词

——SQL terms and NoSQL terms by Victoria Malaya

MongoDB Shell 的一些操作

  1# 命令行输入 mongosh
  2> db
  3test
  4> show databases
  5# 简单用 show dbs
  6admin    size
  7config   size
  8local    size
  9## 创建数据库
 10> use myNewDatabase
 11switched to db myNewDatabase
 12## 新建数据表并在数据表中插入数据
 13myNewDatabase> db.myCollection.insertOne({"name": "tianheg", "age": "21"})
 14{
 15  acknowledged: true,
 16  insertedIds: { '0': ObjectId("62a0388b921cfec2c6bf8cae") }
 17}
 18myNewDatabase> db.myCollection.insertMany([{ name: "tianheg2", age: "22"}, {name: "tianheg3", age: "23" }])
 19{
 20  acknowledged: true,
 21  insertedIds: {
 22    '0': ObjectId("62a0408f921cfec2c6bf8cb0"),
 23    '1': ObjectId("62a0408f921cfec2c6bf8cb1")
 24  }
 25}
 26## 仅新建数据表
 27myNewDatabase> db.createCollection("secondCollection")
 28{ ok: 1 }
 29## 在数据表中查询
 30myNewDatabase> db.myCollection.find({})
 31# 显示全部数据
 32# 相当于 `SELECT * FROM myCollection`
 33myNewDatabase> db.myCollection.find({ name: "tianheg" })
 34# 相当于 `SELECT * FROM myCollection WHERE name = "tianheg"`
 35# 条件查询
 36myNewDatabase> db.myCollection.find({ name: { $in: ["tianheg", "tianheg2" ]}})
 37# 相当于 `SELECT * FROM myCollection WHERE name in ("tianheg", "tianheg2")`
 38myNewDatabase> db.myCollection.find({ name: "tianheg", age: { $lt: "23" }})
 39[
 40  {
 41    _id: ObjectId("62a0388b921cfec2c6bf8cae"),
 42    name: 'tianheg',
 43    age: '21'
 44  }
 45]
 46# 相当于 `SELECT * FROM myCollection WHERE name = "tianheg" AND age < 23`
 47myNewDatabase> db.myCollection.find({ $or: [{ name: "tianheg" } , { age: { $lt: "23" }} ]})
 48[
 49  {
 50    _id: ObjectId("62a0388b921cfec2c6bf8cae"),
 51    name: 'tianheg',
 52    age: '21'
 53  },
 54  { _id: ObjectId("62a03955921cfec2c6bf8caf"), name: 'jim', age: '21' },
 55  {
 56    _id: ObjectId("62a0408f921cfec2c6bf8cb0"),
 57    name: 'tianheg2',
 58    age: '22'
 59  }
 60]
 61# 相当于 `SELECT * FROM myCollection WHERE name = "tianheg" OR age < 23`
 62myNewDatabase> db.myCollection.find({}, {_id: 0} )
 63# 不显示 _id
 64## 更新数据
 65myNewDatabase> db.myCollection.updateOne({ name: "tianheg" }, { $set: { age: "22" }})
 66# 通过 name 找到要修改的数据条目通过 $set 修改对应的数据属性值
 67myNewDatabase> db.myCollection.updateMany({ age: { $lt: "22" } }, { $set: { name: "hello" }})
 68myNewDatabase> db.myCollection.replaceOne({ name: "hello" }, { name: "hello", age: "30"})
 69## 删除数据不删除索引
 70myNewDatabase> db.myCollection.deleteMany({})
 71# 删除表中所有数据
 72myNewDatabase> db.myCollection.deleteOne({ age: "22"})
 73{ acknowledged: true, deletedCount: 1 }
 74# 删除符合条件的第一条数据
 75## Bulkwrite
 76myNewDatabase> try {
 77   db.myCollection.bulkWrite([
 78      { insertOne: { "document": { "_id": 4, "char": "Dithras", "class": "barbarian", "lvl": 4 } } },
 79      { insertOne: { "document": { "_id": 5, "char": "Taeln", "class": "fighter", "lvl": 3 } } },
 80      { updateOne : {
 81         "filter" : { "char" : "Eldon" },
 82         "update" : { $set : { "status" : "Critical Injury" } }
 83      } },
 84      { deleteOne : { "filter" : { "char" : "Brisbane"} } },
 85      { replaceOne : {
 86         "filter" : { "char" : "Meldane" },
 87         "replacement" : { "char" : "Tanys", "class" : "oracle", "lvl": 4 }
 88      } }
 89   ]);
 90} catch (e) {
 91   print(e);
 92}
 93{
 94  acknowledged: true,
 95  insertedCount: 2,
 96  insertedIds: { '0': 4, '1': 5 },
 97  matchedCount: 0,
 98  modifiedCount: 0,
 99  deletedCount: 0,
100  upsertedCount: 0,
101  upsertedIds: {}
102}

MongoDB 大学课程——M001 MongoDB Basics

Free MongoDB Official Courses | MongoDB University

Chapter 1: What is MongoDB?

  1. Why is MongoDB a NoSQL database?

Because it does not utilize tables, rows and columns to organize data.

Because it uses a structured way to store and access data

  1. What is the MongoDB Database?

The MongoDB database is an organized way to store and access data.

MongoDB is a NoSQL database that uses documents to store data in an organized way.

  1. In MongoDB how does a document relate to a collection?

Collections consist of many documents.

Documents are organized into collections, not the other way around.

Rows, columns and tables are not part of the data organization in MongoDB.

  1. In a MongoDB Document what is the role of fields and values?

A field is a unique identifier for a specific datapoint.

Data is organized in field-value pairs, so each field has a value associated with it.


Replica Set - a few connected machines that store the same data to ensure that if something happens to one of the machines the data will remain intact. Comes from the word replicate - to copy something.

Instance - a single machine locally or in the cloud, running a certain software, in our case it is the MongoDB database.

Cluster - group of servers that store your data.


  1. How is MongoDB Atlas related to MongoDB the Database?

Atlas has many tools and services within it that are built specifically for the MongoDB Database.

They both are MongoDB products.

Chapter 2: Importing, Exporting, and Querying Data

MongoDB stores data in BSON, and you can then view it in JSON.

BSON is faster to parse and lighter to store than JSON.

JSON supports fewer data types than BSON.

1mongodump --uri "mongodb+srv://<your username>:<your password>@<your cluster>.mongodb.net/sample_supplies"
2
3mongoexport --uri="mongodb+srv://<your username>:<your password>@<your cluster>.mongodb.net/sample_supplies" --collection=sales --out=sales.json
4
5mongorestore --uri "mongodb+srv://<your username>:<your password>@<your cluster>.mongodb.net/sample_supplies"  --drop dump
6
7mongoimport --uri="mongodb+srv://<your username>:<your password>@<your cluster>.mongodb.net/sample_supplies" --drop sales.json
  1. Which of the following commands will add a collection that is stored in animals.json to an Atlas cluster?

mongoimport can import data from JSON, and other supported non BSON formats.

mongodump exports data in its raw BSON form.

mongorestore imports data from a mongodump created BSON format.

mongoexport does work with JSON, but it would export it, thus making a copy of the data outside of the Atlas cluster, rather than adding a collection to the Atlas cluster.

慢慢筛选数据:={ "birth year": 1961, "start station name": "Howard St & Centre St" }=。

1mongosh "mongodb+srv://<username>:<password>@<cluster>.mongodb.net/admin"
 1show dbs
 2
 3use sample_training
 4
 5show collections
 6
 7db.zips.find({"state": "NY"})
 8
 9db.zips.find({"state": "NY"}).count()
10
11db.zips.find({"state": "NY", "city": "ALBANY"})默认就是 pretty
12
13db.zips.find({"state": "NY", "city": "ALBANY"}).pretty()
  1. What does it do in the mongo shell?

Iterates through the cursor results

  1. Which of the following statements are true about the mongo shell?

It allows you to interact with your MongoDB instance without using a Graphical User Interface.

It is a fully functioning JavaScript interpreter

The mongo shell does not automatically sort results nor does it return data in sorted order by default. However, you can get a sorted set of documents by using the sort() command which will be discussed later in this course.

Chapter 3: Creating and Manipulating Documents

先讲的是 ObjectId 数据类型。

  1. How does the value of _id get assigned to a document?

When a document is inserted a random field is picked to serve as the id field.

这句话错误,我选择了它。

It is automatically generated as an ObjectId type value.

MongoDB generates a value, so that there is one just in case. You can definitely change the default value to a different value or data type, as long as they are unique to this collection and not an array data type.

MongoDB adds an id field to any inserted document if it doesn't have one, and it does not utilize other fields for this purpose.

You can assign the id field values to be sequential integer values, but it is not the default behavior, nor is it best practice.

db.collection.findOne() 用来查看当前 Collection 的 Schema。

  1. Select all true statements from the following list:

If a document is inserted without a provided id value, then the id field and value will be automatically generated for the inserted document before insertion.

MongoDB can store duplicate documents in the same collection, as long as their id values are different.

可以在 MongoDB 网页端进行数据的增删改查(CRUD)。

  1. 找出不属于 MongoDB 数据类型的一组:
{
  "_id": 1,
  "pet": "cat",
  "attributes": [
    { "coat": "fur", "type": "soft" },
    { "defense": "claws", "location": "paws", "nickname": "murder mittens" }
  ],
  "name": "Furball"
}

我看 attributes 不太符合 JSON,结果却是符合的。

这些操作符属于更新操作符。

$inc $set $push

给某属性增加数目:=db.zips.updateMany({ city: "HUDSON" }, { "$inc": { "pop": 10}})=

某属性 改变数目:=db.zips.updateMany({ city: "HUDSON" }, { "$set": { "pop": 12345}})=

添加新项目:=db.grades.updateOne({ "studentid": 151, "classid": 339 }, { "$push": { scores: { type: "extra credit", score: 100}}})=

删除操作

deleteOne(), deleteMany(), drop()

Removing all collections in a database also remove the database.

Chapter 4: Advanced CRUD Operations

更新操作符:=$inc= =$set= $unset

比较查询操作符:

  • $eq Equal
  • $lt less than
  • $lte less than or equal
  • $gt greater than
  • $gte greater than or equal
  • $ne not equal
  • $in in
  • $nin not in
1db.trips.find({ 'birth year': { $gt: 1998 } }).count()
2db.trips.find({ 'birth year': 1998 }).count()

Query Operators - Logic

$not 以外的语法:

1{ "$<operator>": [{ <clause1> }, { <clause2> }, ...]}

$not 的语法:

1{ $not: {<clause>}}
  • $and 默认行为,不指定逻辑操作符时使用
  • $or
  • $not
  • $nor
1db.routes
2  .find({
3    $and: [
4      { $or: [{ dst_airport: 'KZN' }, { src_airport: 'KZN' }] },
5      { $or: [{ airplane: 'CR2' }, { airplane: 'A81' }] },
6    ],
7  })
8  .pretty()

找到在某个数值区间的值:

 1// 我写的
 2db.zips
 3  .find({ $and: [{ pop: { $gte: 5000 } }, { pop: { $lte: 1000000 } }] })
 4  .count()
 5// 答案写的
 6db.zips.find({ pop: { $gte: 5000, $lte: 1000000 } }).count()
 7// 另一种
 8db.zips
 9  .find({ $nor: [{ pop: { $lt: 5000 } }, { pop: { $gt: 1000000 } }] })
10  .count()

目前最复杂的一个:

 1// 自己写的
 2db.companies.find({
 3  $or: [
 4    {
 5      $and: [
 6        { founded_year: 2004 },
 7        { $or: [{ category_code: 'web' }, { category_code: 'social' }] },
 8      ],
 9    },
10
11    {
12      $and: [
13        { founded_month: 10 },
14        { $or: [{ category_code: 'web' }, { category_code: 'social' }] },
15      ],
16    },
17  ],
18})
19
20// 答案
21db.companies
22  .find({
23    $and: [
24      { $or: [{ founded_year: 2004 }, { founded_month: 10 }] },
25      { $or: [{ category_code: 'web' }, { category_code: 'social' }] },
26    ],
27  })
28  .count()

答案更简洁。

$ 除了用在操作符上,还用于获取属性值。

 1db.trips
 2  .find({
 3    $expr: {
 4      $and: [
 5        { $gt: ['$tripduration', 1200] },
 6        { $eq: ['$end station id', '$start station id'] },
 7      ],
 8    },
 9  })
10  .count()

What are some of the uses for the $ sign in MQL?

  • $ denotes an operator.
  • $ signifies that you are looking at the value of that field rather than the field name.

Array Operators

 1db.listingsAndReviews.find({
 2  amenities: {
 3    $size: 20,
 4    $all: [
 5      'Internet',
 6      'Wifi',
 7      'Kitchen',
 8      'Heating',
 9      'Family/kid friendly',
10      'Washer',
11      'Dryer',
12      'Essentials',
13      'Shampoo',
14      'Hangers',
15      'Hair dryer',
16      'Iron',
17      'Laptop friendly workspace',
18    ],
19  },
20})

题目不仔细读个三四遍,就匆忙解答,最后只能答错。

 1// 我写的
 2db.listingsAndReviews
 3  .find(
 4    { property_type: 'House', amenities: { $all: ['Changing table'] } },
 5    { amenities: 1 }
 6  )
 7  .count()
 8// 答案
 9db.listingsAndReviews
10  .find({ property_type: 'House', amenities: 'Changing table' })
11  .count()
1db.listingsAndReviews.find({
2  amenities: {
3    $all: ['Free parking on premises', 'Wifi', 'Airconditioning'],
4  },
5  bedrooms: { $gte: 2 },
6})

Array Operators and Projection

projection 就是可以让属性显示或隐藏的设置区间。

0 表示隐藏某属性,1 表示显示某属性。一般情况下,1 和 0 不能同时出现,但是有例外,当属性为 id 时。

 1db.listingsAndReviews
 2  .find({ amenities: 'Wifi' }, { price: 1, address: 1, _id: 0 })
 3  .count()
 4
 5db.listingsAndReviews.find(
 6  { amenities: 'Wifi' },
 7  { price: 1, address: 1, _id: 0, maximum_nights: 0 }
 8)
 9
10db.companies
11  .find({ offices: { $elemMatch: { city: 'Seattle' } } }, { _id: 0 })
12  .count()

Array Operators and Sub-Documents

 1db.trips.findOne({ 'start station location.type': 'Point' })
 2
 3db.companies.find({ 'relationships.0.person.first_name': 'Mark' }, { name: 1 })
 4
 5db.companies.find(
 6  {
 7    'relationships.0.person.first_name': 'Mark',
 8    'relationships.0.title': { $regex: 'CEO' },
 9  },
10  { name: 1 }
11)
12
13// 答案
14db.trips.find({ 'start station location.coordinates.0': { $lt: -74 } }).count()
15// 我写的错误答案
16db.trips
17  .find({
18    'start station location': { $elemMatch: { 'coordinates[0]': { $eq: 74 } } },
19  })
20  .count()

为什么会写错?

  1. 第一次学习不熟悉
  2. 没有多读几遍题目

Chapter 5: Indexing and Aggregation Pipeline

 1db.listingsAndReviews.aggregate([
 2  { $match: { amenities: 'Wifi' } },
 3  { $project: { price: 1, address: 1, _id: 0 } },
 4])
 5
 6db.listingsAndReviews.find(
 7  { amenities: 'Wifi' },
 8  { price: 1, address: 1, _id: 0 }
 9)
10
11db.listingsAndReviews.aggregate([
12  { $project: { address: 1, _id: 0 } },
13  { $group: { _id: '$address.country' } },
14])
15
16db.listingsAndReviews.aggregate([
17  { $project: { address: 1, _id: 0 } },
18  { $group: { _id: '$address.country', count: { $sum: 1 } } },
19])
20
21db.listingsAndReviews.aggregate([
22  { $project: { reviews: 0 } },
23  { $group: { _id: '$room_type' } },
24])
  • $group 通过 address.country 分组

Aggregation Pipeline 为什么出现?

aggregate() allows us to compute and reshape data in the cursor.

aggregate() can do what find() can and more.

删除当前数据库:=db.dropDatabase()=

 1use sample_training
 2
 3db.zips.find().sort({ "pop": 1 }).limit(1)
 4
 5db.zips.find({ "pop": 0 }).count()
 6
 7db.zips.find().sort({ "pop": -1 }).limit(1)
 8
 9db.zips.find().sort({ "pop": -1 }).limit(10)
10
11db.zips.find().sort({ "pop": 1, "city": -1 })
 1db.companies
 2  .find({ founded_year: { $ne: null } }, { name: 1, founded_year: 1 })
 3  .sort({ founded_year: 1 })
 4  .limit(5)
 5db.companies
 6  .find({ founded_year: { $ne: null } }, { name: 1, founded_year: 1 })
 7  .limit(5)
 8  .sort({ founded_year: 1 })
 9db.trips
10  .find({ 'birth year': { $ne: '' } })
11  .sort({ 'birth year': -1 })
12  .limit(1)

Introduction to Indexes

1db.trips.createIndex({ 'start station id': 1, 'birth year': 1 })

什么是 Data Modeling?

它是一种对数据的组合方式,具体看应用要求。

什么是 Upsert?

Update + Insert。使用时确保数据库的空间足够。并且数据库中没有相同的数据项。

1db.iot.updateOne(
2  { sensor: r.sensor, date: r.date, valcount: { $lt: 48 } },
3  {
4    $push: { readings: { v: r.value, t: r.time } },
5    $inc: { valcount: 1, total: r.value },
6  },
7  { upsert: true }
8)

When upsert is set to true and the query predicate returns an empty cursor, the update operation creates a new document using the directive from the query predicate and the update predicate.

By default upsert is set to false.

When upsert is set to false and the query predicate returns an empty cursor then there will be no updated documents as a result of this operation.

如果通过 MongoDB 认证考试指南:https://university.mongodb.com/exam/guide

M103 Basic Cluster Administration

  1. 一些 Linux 基础

文件系统,=/etc= 存放系统配置文件、=/home= 是用户家目录、=/var= 存放变量文件。

  • pwd print working directory
  • sudo superuser do
  • chmod 改变文件/文件夹的权限、用户和用户组
  • mkdir
  • rm
  • ls
  • cd
  • cat

https://chmod-calculator.com/

usergroupothers
300-wx
400r–
500r-x
600rw-
700rwx
730rwx-wx
740rwxr–
750rwxr-x
760rwxrw-
770rwxrwx
773rwxrwx-wx
774rwxrwxr–
775rwxrwxr-x
776rwxrwxrw-
777rwxrwxrwx

No notes link to this note