+41

[MongoDB P3] Hướng dẫn cài đặt và sử dụng mongodb

Lời mở đầu

Hello các bạn trở lại với series bài viết "Những gì mình biết về MongoDB", series nói về một NoSQL DB cực kỳ phổ biến là MongoDB.

Trong nội dung bài này mình sẽ chia sẻ cách cài đặt mongodb dạng standalone và một số thao tác cơ bản với mongodb như tạo database, tạo collection, thêm sửa xóa dữ liệu cơ bản...

Hướng dẫn cài đặt mongodb

MongoDB có thể được cài đặt trên nhiều platform, từ việc cài gói trên các hệ điều hành như Linux, MacOS, Window.. tới việc cài đặt bằng docker hay cài đặt trên Kubernetes qua các helmchart.

Trong nội dung này mình sẽ hướng dẫn cách cài đặt mongodb trên Linux và cụ thể là Ubuntu phiên bản 20.04. Việc cài đặt trên các HĐH khác cơ bản cũng ko có quá nhiều khác biệt, các bạn có thể tham khảo thêm ở đây

image.png

Cài đặt mongodb trên ubuntu 20.04

Mình sẽ cài đặt bản MongoDB 6.0 Community Edition trên Ubuntu 20.04 LTS Focal. Thủ tục cài đặt khá đơn giản, các bạn follow các bước bên dưới nhé!

Bước 1: Thêm key cho repo phục vụ cài mongodb

wget -qO - https://www.mongodb.org/static/pgp/server-6.0.asc | sudo apt-key add -

Kết quả trả về "OK" là thành công. Còn nếu có lỗi thì các bạn thực hiện thêm bước sau đây rồi thực hiện lại bước trên:

sudo apt-get install -y gnupg
wget -qO - https://www.mongodb.org/static/pgp/server-6.0.asc | sudo apt-key add -

Bước 2: Thêm key cho repo phục vụ cài mongodb

echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/6.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list

Bước 3: Cập nhật lại repo local

sudo apt update -y

Bước 4: Cài đặt gói của mongodb

sudo apt-get install -y mongodb-org

Một lưu khi cài đặt bằng gói trên OS thì chúng ta cần đánh dấu gói cài đặt này không tự động update khi thực hiện update repo bằng cách sau:

echo "mongodb-org hold" | sudo dpkg --set-selections
echo "mongodb-org-database hold" | sudo dpkg --set-selections
echo "mongodb-org-server hold" | sudo dpkg --set-selections
echo "mongodb-mongosh hold" | sudo dpkg --set-selections 
echo "mongodb-org-mongos hold" | sudo dpkg --set-selections
echo "mongodb-org-tools hold" | sudo dpkg --set-selections

Khởi chạy mongodb

Lưu ý về cấu hình ulimit

Bạn cần set giá trị ulimit cho max-open-files tối thiểu là 64000 nếu không thì service mongod sẽ báo lỗi. Giá trị ulimit được set theo từng user của OS, do đó cần set đúng với user dùng để chạy mongodb.

Khi cài đặt bằng package manager như dùng apt trên ubuntu ở bên trên thì giá trị ulimit đã được set tự động rồi, các bạn có thể verify lại như sau:

Bước 1: Kiểm tra PID của mongod

root@mongodb-standalone:/etc/systemd# ps -ef |grep mongod |grep -v grep
mongodb      475       1  0 14:59 ?        00:00:04 /usr/bin/mongod --config /etc/mongod.conf

Bước 2: Kiểm tra các giá trị ulimit của process trên (trong trường hợp này PID=475)

root@mongodb-standalone:/etc/systemd# cat /proc/475/limits
Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        0                    unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             64000                64000                processes
Max open files            64000                64000                files
Max locked memory         unlimited            unlimited            bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       7837                 7837                 signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us

Các bạn sẽ thấy giá trị của tham số "Max open files" đang được set là 64000.

Cấu hình của service mongod

Khi cài gói mongodb-org thì service mặc định mongod được tạo và được định nghĩa bởi file cấu hình service ở đường dẫn /lib/systemd/system/mongod.service.

Trong file config này chứa các tham số để chạy service này, trong đó có tham số quan trọng là ExecStart:

ExecStart=/usr/bin/mongod --config /etc/mongod.conf

Và các bạn có thể thấy file config chính để chạy service này là /etc/mongod.conf. Các bạn hoàn toàn có thể tùy biến đường dẫn tới file config của service, cũng như tùy biến các tham số trong file config này:

storage:
  dbPath: /var/lib/mongodb
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log
net:
  port: 27017
  bindIp: 127.0.0.1

Một số tham số cấu hình quan trọng cần lưu ý:

  • storage: Đường dẫn tới thư mục chứa dữ liệu của mongodb
  • systemLog: Đường dẫn tới thư mục chứa log của service mongod này
  • net: Khai báo Port và IP để bindport. Mặc định sẽ chỉ bind Port (mặc định 27017) vào localhost (127.0.0.1) do đó đứng từ một host khác sẽ không thể kết nối tới db nếu bạn không bind vào các interface khác của host.

Chạy mongodb

Sau khi kiểm tra và tùy biến các tham số cấu hình (nếu muốn) thì ta có thể start mongodb lên. Nếu như bạn có sửa file cấu hình service thì bạn cần reload lại nó bằng lệnh:

sudo systemctl daemon-reload

Sau đó start mongodb:

sudo systemctl enable mongod
sudo systemctl start mongod

Kết quả khi mongod start thành công như sau:

ubuntu@mongodb-standalone:~$ sudo service mongod status
● mongod.service - MongoDB Database Server
     Loaded: loaded (/lib/systemd/system/mongod.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2023-03-18 14:59:01 UTC; 30min ago
       Docs: https://docs.mongodb.org/manual
   Main PID: 475 (mongod)
     Memory: 229.2M
     CGroup: /system.slice/mongod.service
             └─475 /usr/bin/mongod --config /etc/mongod.conf

Mar 18 14:59:01 mongodb-standalone systemd[1]: Started MongoDB Database Server.

Bắt đầu sử dụng mongodb

Lúc này mongodb đã được start lên, các bạn có thể bắt đầu kết nối vào db bằng cách chạy lệnh mongosh trên chính máy chủ bạn đang cài mongodb.

ubuntu@mongodb-standalone:~$ mongosh
Current Mongosh Log ID: 6415d80bfe9ee8d719c45af1
Connecting to:          mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+1.8.0
Using MongoDB:          6.0.5
Using Mongosh:          1.8.0
For mongosh info see: https://docs.mongodb.com/mongodb-shell/
test>

Như vậy chúng ta đã kết nối được tới mongodb và mặc định sẽ kết nối vào database có tên là test.

Các thao tác cơ bản với mongodb

Trước hết, cần nhắc lại là một số khái niệm trên mongodb sẽ khác với các khái niệm ở các Rational Database khác như:

Do đó ở đây chúng ta cần nhớ tổ chức trong mongodb sẽ là: database => collection => document => field.

Tạo mới database trong mongodb với mongosh

Khi lần đầu kết nối vào mongodb thì mình đang được kết nối vào một db trắng là test. Để xem list các database có trong hệ thống ta dùng lệnh:

test> show dbs
admin   40.00 KiB
config  48.00 KiB
local   72.00 KiB

Lưu ý db test là db trắng nên sẽ không được liệt kê ra trong câu lệnh show dbs.

Để tạo mới một DB ta thực hiện lệnh use [database-name]:

test> use demo
switched to db demo
demo> 

Như vậy một DB trắng tên là demo được tạo ra và chúng ta cũng sẽ được tự động chuyển sang DB demo đó luôn. Trong dấu nhắc lệnh sẽ cho chúng ta biết chúng ta đang thao tác trên database nào

Tạo collection mới trong database

Có 2 cách tạo collection trong mongodb:

  • Tạo bằng lệnh createCollection
  • Tạo bằng cách insert dữ liệu vào collection (collection sẽ được tạo nếu nó chưa tồn tại)

Tạo collection bằng lệnh createCollection

Ta có thể thực hiện tạo một Collection mới có tên staff như sau:

demo> db.createCollection("staff")
{ ok: 1 }

Tạo collection bằng lệnh insertOne

demo> db.demo_collection.insertOne({name: "Trinh Quoc Viet", age: "18", gender: "male", cert: ["AWS", "Azure"] })
{
  acknowledged: true,
  insertedId: ObjectId("6415dc28914137d28a613d06")
}

Insert vào collection

Để thêm 1 document vào collection ta dùng lệnh insertOne

demo> db.staff.insertOne({name: "Nguyen Hoang Anh", age: "21", gender: "male", cert: ["GCP", "Azure"] })
{
  acknowledged: true,
  insertedId: ObjectId("6415e280914137d28a613d0b")
}

Để thêm nhiều document vào collection ta dùng lệnh insertMany:

db.staff.insertMany([  
  {
    name: "Trinh Quoc Viet",
    age: "18",
    gender: "male",
    cert: ["AWS", "Azure"]    
  },
 {
    name: "Nguyen Van Anh",
    age: "20",
    gender: "female",    
    cert: ["AWS", "CKA", "CKAD"]
  }
])

Kết quả:

{
  acknowledged: true,
  insertedIds: {
    '0': ObjectId("6415df0b914137d28a613d08"),
    '1': ObjectId("6415df0b914137d28a613d09")
  }
}

Truy vấn dữ liệu trong collection (hàm find)

Có 2 cách sử dụng find trong mongodb là find()findOne()

Sử dụng find()

Để select dữ liệu từ collecion của mongodb, chúng ta có thể sử dụng hàm find(). Hàm này có thể nhận input là một query object để filter dữ liệu. Nếu điều kiện filter này để trống thì sẽ trả về tất cả document của collection này.

Ví dụ select all từ collection staff:

demo> db.staff.find()
[
  {
    _id: ObjectId("6415df0b914137d28a613d08"),
    name: 'Trinh Quoc Viet',
    age: '18',
    gender: 'male',
    cert: [ 'AWS', 'Azure' ]
  },
  {
    _id: ObjectId("6415df0b914137d28a613d09"),
    name: 'Nguyen Van Anh',
    age: '20',
    gender: 'female',
    cert: [ 'AWS', 'CKA', 'CKAD' ]
  },
  {
    _id: ObjectId("6415e280914137d28a613d0b"),
    name: 'Nguyen Hoang Anh',
    age: '21',
    gender: 'male',
    cert: [ 'GCP', 'Azure' ]
  }
]

demo>

Sử dụng findOne()

Sử dụng hàm findOne() để chỉ lựa chọn ra duy nhất một document. Hàm này cũng nhận điều kiệu query dạng object và nếu để trống nó sẽ trả về document đầu tiên nó tìm thấy.

demo> db.staff.findOne()
{
  _id: ObjectId("6415df0b914137d28a613d08"),
  name: 'Trinh Quoc Viet',
  age: '18',
  gender: 'male',
  cert: [ 'AWS', 'Azure' ]
}

Lọc dữ liệu

Ta có thể lọc dữ liệu theo các tham số, ví dụ lọc những staff nào là name (điều kiện là "gender": "male"):

demo> db.staff.find({"gender": "male"})
[
  {
    _id: ObjectId("6415df0b914137d28a613d08"),
    name: 'Trinh Quoc Viet',
    age: '18',
    gender: 'male',
    cert: [ 'AWS', 'Azure' ]
  },
  {
    _id: ObjectId("6415e280914137d28a613d0b"),
    name: 'Nguyen Hoang Anh',
    age: '21',
    gender: 'male',
    cert: [ 'GCP', 'Azure' ]
  }
]

Lọc field cần lấy kết quả bằng projection

Chúng ta có thể lọc ra các field cần thiết bằng cách sử dụng tham số thứ 2 trong hàm find() được gọi là projection. Ví dụ ta chỉ muốn lấy ra thông tin tên và cert của các staff là nam:

demo> db.staff.find({"gender": "male"},{name:1 , cert: 1})
[
  {
    _id: ObjectId("6415df0b914137d28a613d08"),
    name: 'Trinh Quoc Viet',
    cert: [ 'AWS', 'Azure' ]
  },
  {
    _id: ObjectId("6415e280914137d28a613d0b"),
    name: 'Nguyen Hoang Anh',
    cert: [ 'GCP', 'Azure' ]
  }
]
demo>

Cách này có thể lọc những field không mong muốn nhưng trường "_id" nếu ta muốn ẩn nó đi thì phải set cho nó tham số bằng 0 trong cấu hình projection:

demo> db.staff.find({"gender": "male"},{_id: 0, name:1 , cert: 1})
[
  { name: 'Trinh Quoc Viet', cert: [ 'AWS', 'Azure' ] },
  { name: 'Nguyen Hoang Anh', cert: [ 'GCP', 'Azure' ] }
]
demo>

Update dữ liệu trong collection

Để update dữ liệu trong collection ta có thể sử dụng hàm updateOne() hoặc hàm updateMany(). Các hàm này nhận tham số đầu tiên là điều kiện truy vấn để chọn ra các document nào cần update.

Và tham số thứ là một object định nghĩa về các dữ liệu cần update.

Hàm updateOne()

Hàm updateOne() thực hiện update document đầu tiên thỏa mãn với điều kiện query. Ví dụ ta cần update tuổi của các nhân viên nam thành 20:

Kiểm tra dữ liệu trước khi update:

demo> db.staff.find({"gender": "male"})
[
  {
    _id: ObjectId("6415df0b914137d28a613d08"),
    name: 'Trinh Quoc Viet',
    age: '18',
    gender: 'male',
    cert: [ 'AWS', 'Azure' ]
  },
  {
    _id: ObjectId("6415e280914137d28a613d0b"),
    name: 'Nguyen Hoang Anh',
    age: '21',
    gender: 'male',
    cert: [ 'GCP', 'Azure' ]
  }
]

Thực hiện update

demo> db.staff.updateOne({"gender": "male"}, {$set: { "age": 20 }} )
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0
}

**Kết quả sau khi update thì chỉ bản ghi đầu tiên tìm thấy đã được update

demo> db.staff.find({"gender": "male"})
[
  {
    _id: ObjectId("6415df0b914137d28a613d08"),
    name: 'Trinh Quoc Viet',
    age: 20,
    gender: 'male',
    cert: [ 'AWS', 'Azure' ]
  },
  {
    _id: ObjectId("6415e280914137d28a613d0b"),
    name: 'Nguyen Hoang Anh',
    age: '21',
    gender: 'male',
    cert: [ 'GCP', 'Azure' ]
  }
]

Hàm updateMany()

Hàm này sẽ thực hiện update toàn bộ các document thỏa mãn điều kiện query. Ví dụ ta lại update hết các nhân viên nam thành 25 tuổi:

demo> db.staff.updateMany( {"gender": "male"}, {$set: { "age": 25 }} )
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 2,
  modifiedCount: 2,
  upsertedCount: 0
}

Kết quả sau khi update thì toàn bộ bản ghi thỏa mãn điều kiện tìm kiếm đã được update

demo> db.staff.find({"gender": "male"})
[
  {
    _id: ObjectId("6415df0b914137d28a613d08"),
    name: 'Trinh Quoc Viet',
    age: 25,
    gender: 'male',
    cert: [ 'AWS', 'Azure' ]
  },
  {
    _id: ObjectId("6415e280914137d28a613d0b"),
    name: 'Nguyen Hoang Anh',
    age: 25,
    gender: 'male',
    cert: [ 'GCP', 'Azure' ]
  }
]

Delete dữ liệu trong collection

Cũng tương tự như lệnh insert hay update, thì mongodb cũng có 2 hàm delete là deleteOne()deleteMany(). Và vẫn với ý tưởng như trên, deleteOne() sẽ xóa document đầu tiên thỏa mãn điều kiện lọc còn deleteMany() thì xóa tất cả document thỏa mãn điều kiện lọc.

Ví dụ xóa nhân viên là nữ:

demo> db.staff.deleteOne({"gender": "female"})
{ acknowledged: true, deletedCount: 1 }

Xóa toàn bộ nhân viên là nam:

demo> db.staff.deleteMany({"gender": "male"})
{ acknowledged: true, deletedCount: 2 }

Một số thao tác với db và collection

Liệt kê danh sách collection trong db:

db.getCollectionNames()

Xóa một collection:

db.collection_name.drop()
db.staff.drop()

Xóa một database:

demo2> db.dropDatabase()
{ ok: 1, dropped: 'demo2' }

Qua bài viết này hy vọng các bạn mới tìm hiểu về mongodb sẽ có thể cài được một hệ thống lab và thực hiện được những thao tác rất cơ bản với mongodb.

Trong bài tiếp theo mình sẽ hướng dẫn cách cài đặt cụm mongodb sharded cluster với đầy đủ các thành phần đảm bảo các yếu tố về redundancy, high availability và scalable sử dụng sharding và replication.

Nếu thấy bài viết hữu ích thì các bạn hãy ủng hộ bằng cách upvote bài viết để mình thêm động lực viết bài nhé!

Hẹn mọi người ở phần tiếp theo!


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.