MongoDB là một loại cơ sở dữ liệu phi quan hệ được sử dụng rộng rãi, tuy cung cấp khả năng chịu tải tốt và tốc độ tìm kiếm nhanh nhưng làm sao để có thể thực hiện tính toán trên các dữ liệu này là điều mà không phải ai cũng có thể làm được. Trong tuần này, Stringee và các bạn sẽ cùng nhau tìm hiểu phương thức $filter và cách sử dụng nó để lọc dữ liệu từ MongoDB nhé.

1. Filter trong MongoDB

1.1. Filter trong MongoDB là gì?

Filter sẽ chọn một set con của một dữ liệu dựa trên các điều kiện được định nghĩa sau đó trả về một mảng các phần tử trùng khớp với các điều kiện tìm kiếm. Thứ tự các phần tử trong kết quả trả về sẽ được giữ nguyên như trước khi thực hiện lọc.

Để sử dụng hàm này truy vấn trong mongo cli, chúng ta sẽ sử dụng cú pháp là $filter.

1.2. Khả năng tương thích của hàm với các phiên bản MongoDB

$filter có thể được sử dụng cho các phiên bản MongoDB được cài đặt dưới đây:

  • MongoDB Atlas: dịch vụ được triển khai hoàn toàn trên Cloud
  • MongoDB Enterprise: phiên bản trả phí tuy nhiên chúng ta phải tự quản lý
  • MongoDB Community: phiên bản hoàn toàn miễn phí, opensource tuy nhiên chúng ta sẽ phải tự quản lý nó 

1.3. Cú pháp sử dụng

{
    $filter:
      {
         input: <array>,
         cond: <expression>,
         as: <string>,
         limit: <number expression>
      }
}

Trong đó, ta cần lưu ý:

Trường

Mô tả

inputMột mảng các document
condMột mệnh đề điều kiện trả về một kết quả boolean, nó sẽ quyết định việc một document có được trả về trong kết quả của $filter hay không. Thể hiện cho từng phần tử trong input có thể được đặt biến là as.
asGiá trị này là tùy chọn. Được sử dụng để đặt tên cho biến sẽ đại diện cho từng phần tử trong dãy input. Nếu không có tên nào được đặt cho từng phần tử, mặc định Mongo sẽ dùng từ this.
limitGiá trị này là tùy chọn, thể hiện kiểu số hạn chế số lượng kết quả trả về của câu lệnh. Bạn không thể điền trả về -1 giá trị, nếu điền null thì truy vấn sẽ trả về toàn bộ các kết quả thỏa mãn. Thứ tự của kết quả trả về sẽ được giữ nguyên so với chính chúng trong mảng trước khi được filter.

2. Hành vi thực hiện của filter

Một vài ví dụ về $filter:

Filter với mảng hỗn hợp

{
 $filter: {
    input: [ 1, "a", 2, null, 3.1, NumberLong(4), "5" ],
    as: "num",
    cond: { $and: [
       { $gte: [ "$$num", NumberLong("-9223372036854775807") ] },
       { $lte: [ "$$num", NumberLong("9223372036854775807") ] }
     ] }
 }
}

Kết quả truy vấn:

[ 1, 2, 3.1, NumberLong(4) ]

Cùng truy vấn đó nhưng chúng ta bổ sung thêm limit:

{
 $filter: {
    input: [ 1, "a", 2, null, 3.1, NumberLong(4), "5" ],
    as: "num",
    cond: { $and:[
       { $gte: [ "$$num", NumberLong("-9223372036854775807") ] },
       { $lte: [ "$$num", NumberLong("9223372036854775807") ] }
    ] },
    limit: 2
 }
}

>>> Xem thêm bài viết về MongoDB:

Tìm hiểu về cơ sở dữ liệu phi quan hệ MongoDB

Sử dụng map reduce trong MongoDB

Giới thiệu về GridFS trong MongoDB

Giả sử chúng ta thao tác với một collection sales như sau:

db.sales.insertMany( [
   {
      _id: 0,
      items: [
         { item_id: 43, quantity: 2, price: 10 },
         { item_id: 2, quantity: 1, price: 240 }
      ]
   },
   {
      _id: 1,
      items: [
         { item_id: 23, quantity: 3, price: 110 },
         { item_id: 103, quantity: 4, price: 5 },
         { item_id: 38, quantity: 1, price: 300 }
      ]
   },
   {
      _id: 2,
      items: [
         { item_id: 4, quantity: 1, price: 23 }
      ]
   }
] )

Thử filter các document có price lớn hoặc bằng 100:

db.sales.aggregate( [
   {
      $project: {
         items: {
            $filter: {
               input: "$items",
               as: "item",
               cond: { $gte: [ "$$item.price", 100 ] }
            }
         }
      }
   }
] )

Filter này sẽ trả về kết quả:

{
   "_id" : 0,
   "items" : [
      { "item_id" : 2, "quantity" : 1, "price" : 240 }
   ]
}
{
   "_id" : 1,
   "items" : [
      { "item_id" : 23, "quantity" : 3, "price" : 110 },
      { "item_id" : 38, "quantity" : 1, "price" : 300 }
   ]
}
{ "_id" : 2, "items" : [ ] }

3. Sử dụng thuộc tính limit trong truy vấn

Cũng sử dụng lại collection sales ở trên. Chúng ta sử dụng limit để hạn chế số lượng các phần tử được trả về.

db.sales.aggregate( [
   {
      $project: {
         items: {
            $filter: {
               input: "$items",
               cond: { $gte: [ "$$item.price", 100 ] },
               as: "item",
               limit: 1
            }
         }
      }
   }
] )

Filter này sẽ trả về kết quả sau:

{
   "_id" : 0,
   "items" : [
      { "item_id" : 2, "quantity" : 1, "price" : 240 }
   ]
}
{
   "_id" : 1,
   "items" : [
      { "item_id" : 23, "quantity" : 3, "price" : 110 }
   ]
}
{ "_id" : 2, "items" : [ ] }

Sử dụng một điều kiện trả về dạng số. Chúng ta hoàn toàn có thể sử dụng biểu hiện điều kiện như sau:

db.sales.aggregate( [
   {
      $project: {
         items: {
            $filter: {
               input: "$items",
               cond: { $lte: [ "$$item.price", 150] },
               as: "item",
               limit: 2.000
            }
         }
      }
   }
] )

Limit lớn hơn các item có thể match điều kiện:

db.sales.aggregate( [
   {
      $project: {
         items: {
            $filter: {
               input: "$items",
               cond: { $gte: [ "$$item.price", 100] },
               as: "item",
               limit: 5
            }
         }
      }
   }
] )

Kết

Trên đây là bài viết của Stringee về filter trong MongoDB, đây là một API rất hữu dụng với cú pháp đơn giản. Mong rằng các chia sẻ này sẽ giúp ích cho bạn trong quá trình xây dựng các chương trình có sử dụng MongoDB.


Stringee Communication APIs là giải pháp cung cấp các tính năng giao tiếp như gọi thoại, gọi video, tin nhắn chat, SMS hay tổng đài CSKH cho phép tích hợp trực tiếp vào ứng dụng/website của doanh nghiệp nhanh chóng. Nhờ đó giúp tiết kiệm đến 80% thời gian và chi phí cho doanh nghiệp bởi thông thường nếu tự phát triển các tính năng này có thể mất từ 1 - 3 năm.

Bộ API giao tiếp của Stringee hiện đang được tin dùng bởi các doanh nghiệp ở mọi quy mô, lĩnh vực ngành nghề như TPBank, VOVBacsi24, VNDirect, Shinhan Finance, Ahamove, Logivan, Homedy,  Adavigo, bTaskee…

Quý bạn đọc quan tâm xin mời đăng ký NHẬN TƯ VẤN TẠI ĐÂY: