Hướng dẫn using mongodb

Ở bài số 4 các bạn đã biết cách tải và tham chiếu driver tương tác MongoDB trong C# rồi. Ở bài này chúng ta tiếp tục học cách kết nối và truy vấn dữ liệu MongoDB thông qua các Driver đó (bạn mở lại Project WPF trong bài số 4).

Mục tiêu bài này các bạn phải kết nối hiển thị được dữ liệu trong bảng Product lên giao diện Listbox trong WPF như dưới đây:

Hướng dẫn using mongodb
Bước 1:

Làm thế nào để Kết nối dữ liệu MongoDB bằng C#?

Để kết nối tới MongoDB ta dùng lệnh sau:

//tham chiếu thư viện này:
using MongoDB.Driver;
//Dùng MongoClient để kết nối tới Server
MongoClient client = new MongoClient("mongodb://localhost:27017");
//Dùng lệnh GetDatabase để kết nối Cơ sở dữ liệu
IMongoDatabase database = client.GetDatabase("QuanLySanPham");

Các Em lưu ý lệnh:

mongodb://localhost:27017

Là cú pháp kết nối lên Server. Chúng ta chỉ đổi localhost thành tên Server(địa chỉ IP) và Port. Còn mọi thứ phải giữ nguyên. Đây là bản Standalone, nếu bạn đang dùng Replica Set thì thay đổi khác chút xíu (Đây là phần nâng cao, khoan hãy quan tâm).

Lệnh:

client.GetDatabase(“QuanLySanPham“);

Dùng để kết nối tới Cơ sở dữ liệu tên là QuanLySanPham, do đó bạn muốn kết nối tới Cơ sở dữ liệu khác thì đổi tên chỗ này là xong.

Bước 2:

Truy vấn dữ liệu, trong bài này ta sẽ truy vấn bảng Product nha.

//Gọi hàm GetCollection để truy suất bảng dữ liệu
IMongoCollection collection = database.GetCollection("Product");
//Muốn truy vấn toàn bộ dữ liệu trong bảng dùng lệnh dưới đây:
List documents = collection.Find(new BsonDocument()).ToList();

Để lấy dữ liệu từng đối tượng (JSON, vì sao nó là JSon thì các Em xem lại các bài trước, hoặc ở đây) trong documents ra ta làm như sau:

//Các em có thể hiểu document là 1 đối tượng đang duyệt (là Json) trong tập các Json được lưu trong biến documents
foreach (BsonDocument document in documents)
{
//Cột Ma (là thuộc tính Ma của đối tượng Product đang duyệt) có kiểu chuỗi
string ma = document["Ma"].AsString;
//Cột Ten (là thuộc tính Ten của đối tượng Product đang duyệt) có kiểu chuỗi
string ten = document["Ten"].AsString;
//Cột DonGia (là thuộc tính DonGia của đối tượng Product đang duyệt) có kiểu Double
double gia = document["DonGia"].AsDouble;

}

Coding chi tiết:

-Phần XAML (MainWindow.xaml):

-Phần Coding(MainWindow.xaml,cs):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using MongoDB.Bson;
using MongoDB.Driver;

namespace CSharpMongoDBExample
{
///

/// Interaction logic for MainWindow.xaml
/// 

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

private void btnGetProduct_Click(object sender, RoutedEventArgs e)
{
MongoClient client = new MongoClient("mongodb://localhost:27017");
IMongoDatabase database = client.GetDatabase("QuanLySanPham");

IMongoCollection collection = database.GetCollection("Product");
List documents = collection.Find(new BsonDocument()).ToList();
lstProduct.Items.Clear();
foreach (BsonDocument document in documents)
{
string ma = document["Ma"].AsString;
string ten = document["Ten"].AsString;
double gia = document["DonGia"].AsDouble;
lstProduct.Items.Add(ma + "\t" + ten + "\t" + gia);
}

}
}
}

Chạy lên ta sẽ kết quả như mong muốn!

Bạn có thể tải source code của bài này tại đây: Source code here

Bài sau ta sẽ nghiên cứu cách thức tải dữ liệu lớn từ MongoDB về client

Các khóa học online khác, bạn có thể tham khảo tại đây: http://communityuni.com/

Chúc các bạn thành công!

Bài viết được sự cho phép của tác giả Nguyễn Hữu Đồng

Như các bạn đã biết, mongodb là một cơ sở dữ liệu không có quan hệ rất nổi tiếng (NoSQL). Thay vì việc sử dung các bảng có các thuộc tính cố định, mongodb lưu trữ dữ liệu dưới dạng document, dạng key-value, mongodb cũng hỗ trợ scale ngang khi prod lớn lên. Trong bài này mình sẽ hướng dẫn các bạn setup cluster theo phong cách mi ăn liền.

Trước khi bắt đầu các bạn hãy nhìn qua hình dưới đây là cách mà mongo cluster hoạt động

Hướng dẫn using mongodb

Nhìn vào hình trên cluster gồm 3 phần chính.

  • shard: Mỗi shard chứa đựng một tập nhỏ các data đã sharded, từ phiên bản 3.6 trở lên, shards phải được cấu hình chạy replicaset nếu muốn trở thành một phần của cluster.
  • mongos: Đây thực ra là một query router, cung cấp một giao diện tương tác giữa ứng dụng và các sharded cluster.
  • config servers: Config server chứa đựng metadata và cấu hình cho cluster, từ phiên bản 3.4 trở lên config server phải deploy dưới dạng replicaset.

Chuẩn bị

Dể cài đặc chúng ta cần phải chuẩn bị đủ ba phần của cluster,bao gồm 2 config sever, 1 query router server, và 1 shard. Đối với shard mình sẽ dùng 2 server chạy replicaset, mặc dù có thể dùng docker để gộp lại nhưng làm vậy sẽ mất tính tổng quan và rườm ra.

Trước khi bắt đầu chúng ta phải chuẩn bị mongo-keyfile. Mongo keyfile thứ giúp các server xác định là chúng nó là gà cùng một mẹ. Mình sẽ chỉ authenticate bằng mongo-keyfile để cho nó đơn giản, nếu các bạn muốn authen bằng cả username và password thì trên 2 con server config, và 2 con server để tạo 1 shard các bạn dùng mongo shell để tạo username và password cho nó. Trên cả 4 con server đó bạn chạy các lệnh sau

mongo
# lệnh trên dùng mongo shell để kết nối tới server, vì lúc đầu chưa # có username hay password gì cả nên bạn sẽ vào đượcuse admin
# lệnh trên dùng database admin,để lưu trữ những user mà ta sẽ tạo 
# phía saudb.createUser({user: "mongo-admin", pwd: "123", roles:[{role: "root", db: "admin"}]})
# lệnh trên tạo ra một user có username là "mongo-admin" và password # là "123" trên và có vai trò là root của database có tên là admin

Để tạo ra key file các bạn dùng lệnh.

openssl rand -base64 756 > mongo-keyfile

Sau Khi tạo ra keyfile, hãy copy chúng lên trên cả 5 con server, đặt trong /opt/mongo và phân quyền cho file đó, chỉ phân quyền cho file đó.

# sudo mkdir /opt/mongo
# tạo folder nếu chưa có# sudo mv ~/mongo-keyfile /opt/mongo
# nếu bạn dùng SSH để copy thì nhớ copy vào /opt/mongo # lệnh bên dưới chmod 400 set quyền chỉ đọc cho người sở hữu còn lại # thì không có quyền hạn gì cả
sudo chmod 400 /opt/mongo/mongo-keyfile# lệnh dưới gán quyền sở hữu cho mongodb, kết hợp với lệnh trên thì chỉ có mongodb mới có quyền đọc( ngoại lệ đối với root, root là full quyền)
sudo chown mongodb:mongodb /opt/mongo/mongo-keyfile

Để cho đơn giản mình giả sử bạn có 5 con server có ip và port mở như bên dưới. Chúng nó đều có thể kết nối tới nhau.

# 2 config server mình sẽ gán nó là conf1:27017 và conf2:27017
- 100.100.100.101:27017
- 100.100.100.102:27017
# 1 con router server mình sẽ gán nó à router:27017
- 200.200.200.200:27017
# 2 con server để tạo ra một con shard chạy replicaset mình sẽ gán   luôn là shard1
- 300.300.300.301:27017
- 300.300.300.302:27017

Rồi bắt đầu, chúng ta sẽ bắt đầu setup config server chạy replicatSet trước.

BƯỚC 1 : CÀI ĐẶT CONFIG SERVER

Chui vào cả hai con config server. Sửa nội dung file /etc/mongod.conf lại sao cho đúng, cho nó bindIp đúng với ip của nó và thêm field xác thực nhau bằng mongo-keyfile ,replication replSetName và trong file đó. Ngoài ra thêm sharding clusterRole cho cả hai server, nội dung file có thêm vài trường như bên dưới. Đảm bảo là các bạn đã thực hiện trên hai server conf1 và conf2.

port: 27017
  bindIp: 100.100.100.101security: 
  authorization: enabled
  keyFile: /opt/mongo/mongo-keyfilereplication:
  replSetName: configReplSetsharding:
  clusterRole: "configsvr"

Sau đó bạn hãy start mongod trên 2 con config server.

sudo systemctl start mongod

Sau đó dùng dùng kết nối vào 1 trong hai con config server, để kết nối 2 con lại với nhau.

mongo 100.100.100.101:27017 -u mongo-admin -p 123 --authenticationDatabase admin

Từ mongo shell các bạn chạy tiếp lệnh sau

rs.initiate( { _id: "0", configsvr: true, members: [ { _id: 0, host: "100.100.100.101:27017" }, { _id: 1, host: "100.100.100.102:27017" }] } )# lệnh trên khởi tạo 1 replicaSet gồm 2 con config server, các bạn nhớ ghi đúng ip nhé.

Nếu bạn làm đúng như vậy thì sẽ nhận được một message bên dưới báo hiệu 2 config server của chúng ta đã sẵn sàng cho chạy replicaSet.

{ "ok" : 1 }

Để kiểm tra tình trạng của 2 con server các bạn chạy lệnh

rs.status()

Nếu kết quả như bên dưới thì chúng mừng bạn đã setup thành công config server.

configReplSet:SECONDARY> rs.status()
{
    "set" : "configReplSet",
    "date" : ISODate("2020-02-20T14:11:18.382Z"),
    "myState" : 1,
    "term" : NumberLong(1),
    "configsvr" : true,
    "heartbeatIntervalMillis" : NumberLong(2000),
    "members" : [
        {
            "_id" : 0,
            "name" : "100.100.100.101:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 272,
            "optime" : {
                "ts" : Timestamp(1479823872, 1),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2020-02-20T14:11:18.382Z"),
            "infoMessage" : "could not find member to sync from",
            "electionTime" : Timestamp(1479823871, 1),
            "electionDate" : ISODate("2020-02-20T14:11:18.382Z"),
            "configVersion" : 1,
            "self" : true
        },
        {
            "_id" : 1,
            "name" : "100.100.100.102:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 17,
            "optime" : {
                "ts" : Timestamp(1479823872, 1),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2020-02-20T14:11:18.382Z"),
            "lastHeartbeat" : ISODate("2020-02-20T14:11:18.382Z"),
            "lastHeartbeatRecv" : ISODate("2020-02-20T14:11:18.382Z"),
            "pingMs" : NumberLong(1),
            "syncingTo" : "100.100.100.101:27019",
            "configVersion" : 1
        }
       ],
    "ok" : 1
}

BƯỚC 2: CÀI ĐẶT QUERY ROUTER

Trong bước này, chúng ta sẽ cài đặt MongoDB query router, nó sẽ thu lượm thông tin metadata từ config servers, cache nó và sự dụng để gửi các request đọc ghi đến đúng shards. Cài đặt query router thực chất là chạy một tiến trình mongos ta có thể đăng kí nó như là một systemd service. Nhưng trước hết phải tạo file config cho mongos , file config cho mongos đặt ở /etc/mongos.conf

# chỉ định nơi để ghi log.
systemLog:
 destination: file
 logAppend: true
  path: /var/log/mongodb/mongos.log

# cài đặt mạng bind trên ip
net:
 port: 27017
 bindIp: 200.200.200.200# sử dụng mongo-keyfile để authenticate trong cluster
security:
 keyFile: /opt/mongo/mongo-keyfile# setup config server cho nó
sharding:
 configDB: configReplSet/100.100.100.101:27017,100.100.100.101:27017

Sau đó ta sẽ đăng kí mongos với systemd. Tạo một file lib/systemd/system/mongos.service với nội dung như bên dưới.

[Unit]
Description=Mongo Cluster Router
After=network.target

[Service]
User=mongodb
Group=mongodb
ExecStart=/usr/bin/mongos --config /etc/mongos.conf
# file size
LimitFSIZE=infinity
# cpu time
LimitCPU=infinity
# virtual memory size
LimitAS=infinity
# open files
LimitNOFILE=64000
# processes/threads
LimitNPROC=64000
# total threads (user+kernel)
TasksMax=infinity
TasksAccounting=false

[Install]
WantedBy=multi-user.target

Để mongos chạy thì phải tắt phải mongod tránh trường hợp confic data, sau khi tắt thì sẽ enable các mongos service đó và start nó. Tiếp theo là check status của mongos.

sudo systemctl stop mongod
sudo systemctl enable mongos.service
sudo systemctl start mongos
sudo systemctl status mongos

Nếu các bạn làm đúng như trên thì output sẽ tương tự như bên dưới.

Loaded: loaded (/lib/systemd/system/mongos.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2020-02-20 19:43:05 UTC; 10s ago
Main PID: 3901 (mongos)
CGroup: /system.slice/mongos.service
    └─3901 /usr/bin/mongos --config /etc/mongos.conf

Vậy là bạn đã setup thành công query router server .

Tìm việc database hấp dẫn tại TopDev

Tìm việc MongoBD lương cao cho bạn

BƯỚC 3: THÊM SHARD VÀO SERVER

Trước khi thêm shard vào server thì các bãn hãy setup 2 con server còn lại để chúng nó chạy replicaSet với nhau. Setup giống hoàn toàn so với config server chỉ khác là trong file config. Thay vì vai trò của nó là config server thì vai trò của nó là “shardsvr” còn tên replicaSet thì để nguyên cũng được, không thì các bạn đổi tùy thích. Còn IP thì các bạn bind cho đúng

  • 300.300.300.301
  • 300.300.300.302
sharding:
    clusterRole: shardsvr

Sau khi setup xong 2 con server chạy replicaSet thì mình sẽ tiến hành đưa nó vào shard.

Từ một trong hai server vừa mới setup đó (hoặc ở đâu cũng được) , bạn hãy kết nối đến query router.

mongo 200.200.200.200:27017 -u mongo-admin -p 123 --authenticationDatabase admin

Sau khi kết nối thành công các bạn chạy lệnh sau để add shard chúng ta vừa mới tạo ra để đưa nó vào cluster. Giả sử lúc nãy các bạn setup shard chạy replicaSet với name là rs999.

sh.addShard( "rs999/300.300.300.301:27017,300.300.300.302:27017")

Tại thời điểm này, các bạn đã setup thành công cluster. Để test liệu nó có hoạt động hay không các bạn hãy kết nối từ máy của bạn tới query router server.

Nếu kết nối được chúng ta sẽ thử kích hoạt tính năng sharding ở tầng database.

mongo 200.200.200.2000:7017 -u mongo-admin -p 123 --authenticationDatabase admin

Sau đó từ mongo shell, mình sẽ tạo một database tên là demo và kích hoạt sharding trên database demo.

use demo
sh.enableSharding("demo")

Để kiểm tra rằng việc sharding đã thành công mình chuyển qua database config, nơi chứa thông tin của hệ thống.

use config
db.databases.find()

Nếu trả về kết quả như bên dưới thì chúc mừng bạn đã thành công.

{ "_id" : "demo", "primary" : "shard0001", "partitioned" : true }