# Lesson 11 - Data management

Thuật ngữ "quản lý dữ liệu" được sử dụng để ám chỉ việc xử lý dữ liệu trong ứng dụng hoặc hệ thống thông qua các tính năng như phân trang, tìm kiếm, sắp xếp,... Có một số lý do tại sao người ta thường sử dụng thuật ngữ này:

1. **Mục tiêu rõ ràng**: "Quản lý dữ liệu" thể hiện rõ ràng mục tiêu của các tính năng này, đó là giúp người dùng quản lý và tương tác với dữ liệu một cách hiệu quả.
2. **Phổ biến và dễ hiểu**: Thuật ngữ "quản lý dữ liệu" là phổ biến và dễ hiểu trong lĩnh vực phát triển phần mềm và quản lý dữ liệu. Người dùng và nhà phát triển dễ dàng hiểu ý nghĩa của nó.
3. **Tính tổng quan**: "Quản lý dữ liệu" thường ám chỉ một loạt các hoạt động liên quan đến xử lý dữ liệu, bao gồm cả tìm kiếm, sắp xếp, lọc, cắt trang, và nhiều tác vụ khác. Do đó, nó là một thuật ngữ tổng quan hợp lý.

## Phân trang

Phân trang trong ứng dụng web hoặc trong việc hiển thị dữ liệu là một phần quan trọng để cải thiện trải nghiệm người dùng và quản lý hiệu quả lượng dữ liệu lớn. Một số lợi ích như:

1. **Tải trang nhanh hơn**: Giúp tải trang web nhanh hơn bằng cách hiển thị chỉ một phần dữ liệu trên mỗi trang.
2. **Tăng hiệu suất**: Cải thiện hiệu suất tổng thể của ứng dụng hoặc trang web bằng cách tối ưu hóa việc hiển thị dữ liệu.
3. **Trải nghiệm người dùng tốt hơn**: Giúp người dùng dễ dàng tìm kiếm thông tin và tạo trải nghiệm tốt hơn.
4. **Quản lý dữ liệu hiệu quả**: Hỗ trợ quản lý dữ liệu một cách hiệu quả và giảm sự phức tạp.
5. **Tiết kiệm băng thông**: Giảm tải băng thông và tối ưu hóa mạng cho cả người dùng và máy chủ.

Phân trang có thể thực hiện ở cả client và server, tùy thuộc vào yêu cầu cụ thể của ứng dụng và tình huống.

1. **Phân trang ở Server**:
   * Khi bạn có một lượng dữ liệu lớn hoặc dự kiến lượng dữ liệu lớn sẽ tải về từ cơ sở dữ liệu.
   * Khi bạn muốn kiểm soát tối đa hiệu suất và tải trang nhanh cho người dùng bằng cách chỉ gửi dữ liệu cần thiết.
   * Khi cần áp dụng quyền truy cập và kiểm soát dữ liệu động dựa trên người dùng.
2. **Phân trang ở Client**:
   * Khi lượng dữ liệu không lớn và dễ quản lý ở phía client mà không cần gọi đến server.
   * Khi bạn muốn giảm tải cho máy chủ và tăng hiệu suất của ứng dụng.
   * Khi bạn muốn tạo trải nghiệm người dùng mượt mà bằng cách tải nhanh các trang ban đầu và tải thêm dữ liệu khi cần.

#### Phân trang với mongoose

#### Logic phân trang

Trong logic phân trang, ta cần phải tìm được 4 tham số sau cũng như tác dụng của chúng:

1. totalItems - Tổng số lượng data (tổng số lượng phần tử).
2. pageSize - Số lượng phần tử trên một trang.
3. totalPages - Tổng số trang với số lượng totalItems và pageSize cung cấp.
4. skip - vị trí của dữ liệu đầu tiên tại trang cần truy vấn.&#x20;

#### Áp dụng

Áp dụng với mongoose ta sẽ có logic như sau:

```javascript
const totalItems = await YourModel.countDocuments();

const totalPages = Math.ceil(totalItems / pageSize);
// Tính toán vị trí bắt đầu của trang hiện tại, trừ 1 vì mảng bắt đầu từ vị trí 0
const skip = (pageNumber - 1) * pageSize;

// Truy vấn dữ liệu sử dụng Mongoose
const result = await YourModel.find()
  .skip(skip)
  .limit(pageSize);
  
const data = {
   totalItems,
   totalPages,
   currentPage: pageNumber,
   items: result,
}
```

{% hint style="info" %}

* Với client, ta vẫn sử dụng các tham số trên, kết hợp với phương thức slice của mảng để phân trang.
* Ngoài cách phân trang truyền thống trên client, có thể sử dụng kỹ thuật Infinity Scroll để tối ưu
  {% endhint %}

## Lọc - tìm kiếm

Chức năng lọc hay tìm kiếm, đều chung một logic là dựa trên một điều kiện đầu vào và trả ra kết quả với dữ liệu thoả mãn được điều kiện đó.

#### Thực hiện với mongoose

Trong mongoose, với phương thức find, tham số đầu tiên sẽ là một object, chưa các key là trường cần tìm kiếm, value là giá trị điều kiện. Ví dụ:

```javascript
const result = await YourModel.find({
    userName: 'MindX'
});
```

{% hint style="info" %}

* Có thể áp dụng các toán tử của MongoDB để linh hoạt truy vấn với điều kiện.
* Với các phương thức về findBy... thì chỉ cần truyền dữ liệu tương ứng vào tham số đầu tiên.
  {% endhint %}

## Sắp xếp

Sắp xếp là một kỹ thuật sắp xếp thứ tự các phần tử theo một điều kiện nào đó.

Để sử dụng với mongoose, ta sẽ sử dụng phương thức sort, với tham số đầu vào là một object, chứa các key là các trường cần sắp xếp theo, giá trị là 1, -1 hoặc 0, với:

* 1: Sắp xếp tăng đần
* -1: Sắp xếp giảm dần
* 0: Giữ nguyên

{% hint style="info" %}
Kỹ thuật này sẽ không làm thay đổi thứ tự trong database
{% endhint %}

Sử dụng với mongoose như ví dụ sau:

<pre class="language-javascript"><code class="lang-javascript"><strong>const data = await YourModel.find().sort({ fieldName: 1 });
</strong></code></pre>

## Thực hành

Thực hiện áp dụng các kỹ thuật sau:

1. Thực hiện tìm kiếm bài post với tên bài post, content, thời gian tạo, người tạo.
2. Thực hiện phân trang cho danh sách bài post.
3. Sắp xếp các bài post theo thời gian tạo.

## Kết

Trên đây là một số kỹ thuật quản lý dữ liệu được áp dụng phổ biến trên các ứng dụng hiện nay, mọi thứ đều xoay quanh CRUD, nhưng chỉ khác nhau về nghiệp vụ cần được áp dụng, đôi khi ta sẽ cần linh hoạt, lồng ghép các kỹ thuật này lại với nhau.
