Nhóm trong mongodb

Tập hợp là một khung tổng hợp dữ liệu của MongoDB. Tập hợp được xây dựng dựa trên mô hình xử lý dữ liệu bên dưới định dạng đường ống. Aggregation pipeline bao gồm nhiều giai đoạn. Trong mỗi giai đoạn, chúng ta sử dụng một toán tử tổng hợp để biến đổi dữ liệu của các tài liệu đầu vào. Tài liệu đầu ra của giai đoạn phía trước sẽ là tài liệu đầu vào của giai đoạn ngay sau. Toán tử tổng hợp có thể được sử dụng nhiều lần trong đường ống, ngoại trừ $out, $merge$geoNear

Điểm mạnh của aggregation framework là

  • Xử lý nhanh và mạnh với ít băng thông
  • Giải quyết các yêu cầu phức tạp
  • It could work with large data

MongoDB cung cấp phương thức db.collection.aggregate() để chạy đường dẫn tổng hợp

cú pháp

1

2

db. Bộ sưu tập người dùng. tổng hợp( [ { & . lt;stage 1> }, { <stage 2> }, .. . , { <stage N> } ], { <options> } );

 

in which

  • Giai đoạn được đặt trong một mảng theo thứ tự thực hiện trước sau
  • Các tùy chọn là tùy chọn, không nhất thiết phải có

Để minh họa cho các nhà điều hành, mình sẽ sử dụng 2 bộ sưu tập là orderscustomers

Bộ sưu tập orders

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

/* 1 */

{

    "_id" . ObjectId("5dfed89743e6fed50628907c"),

    "cust_id" . "A123",

    "sản phẩm" . [

        "quả táo",

        "chanh"

    ],

    "số tiền" . 500,

    "trạng thái" . "hoàn thành"

}

 

/* 2 */

{

    "_id" . ObjectId("5dfed8a643e6fed50628908a"),

    "cust_id" . "B456",

    "sản phẩm" . [

        "chanh"

    ],

    "số tiền" . 100,

    "trạng thái" . "đang xử lý"

}

 

/* 3 */

{

    "_id" . ObjectId("5dfed8b043e6fed50628908f"),

    "cust_id" . "B456",

    "sản phẩm" . [

        "quả táo",

        "cam"

    ],

    "số tiền" . 300,

    "trạng thái" . "hoàn thành"

}

 

/* 4 */

{

    "_id" . ObjectId("5dfed8b943e6fed506289094"),

    "cust_id" . "C789",

    "sản phẩm" . [

        "quả táo",

        "chanh",

        "cam"

    ],

    "số tiền" . 800,

    "trạng thái" . "hoàn thành"

}

 

/* 5 */

{

    "_id" . ObjectId("5dfed8c343e6fed506289097"),

    "cust_id" . "A123",

    "sản phẩm" . [

        "quả táo"

    ],

    "số tiền" . 250,

    "trạng thái" . "hoàn thành"

}

 

Bộ sưu tập customers

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

/* 1 */

{

    "_id". "A123",

    "tên". "Alice"

}

 

/* 2 */

{

    "_id". "B456",

    "tên". "Bob"

}

 

/* 3 */

{

    "_id". "C789",

    "tên". "Carol"

}

 


2. ________số 8

$match được sử dụng để lọc các tài liệu theo một điều kiện nào đó. $match tương tự như $merge1 và $merge2 trong SQL

cú pháp

1

2

{ $khớp. { <truy vấn> } }

 

Cú pháp truy vấn của $match y cú pháp của truy vấn thao tác đọc (tương tự như $merge4)

Ví dụ

Lọc đơn hàng của khách hàng có ID là A123

1

2

3

4

5

6

7

8

db. đơn đặt hàng. tổng hợp([

    {

        $trận đấu. {

            cust_id. "A123"

        }

    }

])

 

=> Kết quả

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

/* 1 */

{

    "_id" . ObjectId("5dfed89743e6fed50628907c"),

    "cust_id" . "A123",

    "sản phẩm" . [

        "quả táo",

        "chanh"

    ],

    "số tiền" . 500,

    "trạng thái" . "hoàn thành"

}

 

/* 2 */

{

    "_id" . ObjectId("5dfed8c343e6fed506289097"),

    "cust_id" . "A123",

    "sản phẩm" . [

        "quả táo"

    ],

    "số tiền" . 250,

    "trạng thái" . "hoàn thành"

}

 


3. $merge5

$merge5 được sử dụng để chỉ định các trường sẽ xuất hiện trong tài liệu đầu ra. Đó có thể là các trường đã tồn tại trong tài liệu đầu vào, hoặc cũng có thể là các trường được tính toán mới. $merge5 tương tự như $merge8 trong SQL

cú pháp

1

2

{ $dự án. { <đặc điểm kỹ thuật(s)> } }

 

in which

$merge9 may have a following format

  • $geoNear0. trường $geoNear1 sẽ không xuất hiện trong tài liệu đầu ra (default $geoNear1 luôn xuất hiện trong tài liệu đầu ra)
  • $geoNear3. trường X sẽ xuất hiện trong tài liệu đầu ra
  • $geoNear4. trường X sẽ được tính toán dựa trên bất kỳ biểu thức nào

Ví dụ

1

2

3

4

5

6

7

8

9

10

db. đơn đặt hàng. tổng hợp([

    {

        $dự án. {

            _id. 0,

            cust_id. 1,

            new_amount. { $thêm. ["$amount", 100] }

        }

    }

])

 

=> Kết quả

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

/* 1 */

{

    "cust_id" . "A123",

    "số_lượng_mới" . 600. 0

}

 

/* 2 */

{

    "cust_id" . "B456",

    "số_lượng_mới" . 200. 0

}

 

/* 3 */

{

    "cust_id" . "B456",

    "số_lượng_mới" . 400. 0

}

 

/* 4 */

{

    "cust_id" . "C789",

    "số_lượng_mới" . 900. 0

}

 

/* 5 */

{

    "cust_id" . "A123",

    "số_lượng_mới" . 350. 0

}

 


4. $geoNear5

$geoNear5 mới xuất hiện trong MongoDB phiên bản 3. 4. $geoNear5 trả về bổ sung trong đầu ra một trường X chứa tổng số tài liệu đầu vào

cú pháp

1

2

{ $số lượng. <chuỗi> }

 

in which

$geoNear8 là tên của trường X, phải trống khác, không được bắt đầu bằng ký tự $geoNear9 và không được bao gồm ký tự db.collection.aggregate()0

Ví dụ

1

2

3

4

5

6

db. đơn đặt hàng. tổng hợp([

    {

        $số lượng. "tổng"

    }

])

 

=> Kết quả

1

2

3

4

5

/* 1 */

{

    "tổng" . 5

}

 


5. db.collection.aggregate()1 và db.collection.aggregate()2

db.collection.aggregate()1 was used to limit the quality output document. db.collection.aggregate()2 was used to only the value of document will drop in output (tính từ tài liệu đầu tiên). db.collection.aggregate()1 và db.collection.aggregate()2 tương tự như db.collection.aggregate()7 và db.collection.aggregate()8 trong SQL

cú pháp

1

2

{ $giới hạn. <dương số nguyên> }

 

1

2

{ $bỏ qua. <dương số nguyên> }

 

Ví dụ

Nhận lệnh thứ 3 và thứ 4

1

2

3

4

5

6

7

8

9

db. đơn đặt hàng. tổng hợp([

    {

        $bỏ qua. 2

    },

    {

        $giới hạn. 2

    }

])

 

=> Kết quả

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

/* 1 */

{

    "_id" . ObjectId("5dfed8b043e6fed50628908f"),

    "cust_id" . "B456",

    "sản phẩm" . [

        "quả táo",

        "cam"

    ],

    "số tiền" . 300,

    "trạng thái" . "hoàn thành"

}

 

/* 2 */

{

    "_id" . ObjectId("5dfed8b943e6fed506289094"),

    "cust_id" . "C789",

    "sản phẩm" . [

        "quả táo",

        "chanh",

        "cam"

    ],

    "số tiền" . 800,

    "trạng thái" . "hoàn thành"

}

 


6. db.collection.aggregate()9

db.collection.aggregate()9 được dùng để sắp xếp các tài liệu trong đầu ra theo một tiêu chí nào đó. db.collection.aggregate()9 tương tự như orders2 trong SQL

cú pháp

1

2

{ $sắp xếp. { <trường1 . >: <sắp xếp thứ tự . >, <field2>: <sắp xếp thứ tự . > .. . } }

 

Trong đó, orders3 có thể có các giá trị sau

  • orders4. sắp xếp theo thứ tự tăng dần
  • orders5. sắp xếp theo thứ tự giảm dần

Ví dụ

Sắp xếp các thứ tự theo thứ tự giảm dần của số tiền

1

2

3

4

5

6

db. đơn đặt hàng. tổng hợp([

    {

        $sắp xếp. { số tiền. -1 }

    }

])

 

=> Kết quả

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

/* 1 */

{

    "_id" . ObjectId("5dfed8b943e6fed506289094"),

    "cust_id" . "C789",

    "sản phẩm" . [

        "quả táo",

        "chanh",

        "cam"

    ],

    "số tiền" . 800,

    "trạng thái" . "hoàn thành"

}

 

/* 2 */

{

    "_id" . ObjectId("5dfed89743e6fed50628907c"),

    "cust_id" . "A123",

    "sản phẩm" . [

        "quả táo",

        "chanh"

    ],

    "số tiền" . 500,

    "trạng thái" . "hoàn thành"

}

 

/* 3 */

{

    "_id" . ObjectId("5dfed8b043e6fed50628908f"),

    "cust_id" . "B456",

    "sản phẩm" . [

        "quả táo",

        "cam"

    ],

    "số tiền" . 300,

    "trạng thái" . "hoàn thành"

}

 

/* 4 */

{

    "_id" . ObjectId("5dfed8c343e6fed506289097"),

    "cust_id" . "A123",

    "sản phẩm" . [

        "quả táo"

    ],

    "số tiền" . 250,

    "trạng thái" . "hoàn thành"

}

 

/* 5 */

{

    "_id" . ObjectId("5dfed8a643e6fed50628908a"),

    "cust_id" . "B456",

    "sản phẩm" . [

        "chanh"

    ],

    "số tiền" . 100,

    "trạng thái" . "đang xử lý"

}

 


7. orders6

orders6 được dùng để gom nhóm các tài liệu đầu vào theo biểu thức $geoNear1. Mỗi nhóm tương ứng với một tài liệu đầu ra. Trong orders6, chúng ta có thể sử dụng các biểu thức tích lũy như customers0, customers1, customers2, customers3, …

orders6 tương tự như customers5 trong SQL

cú pháp

1

2

3

4

5

6

7

8

9

{

  $nhóm.

    {

      _id. <biểu thức>, // Group By Expression

      <trường1>: { <accumulator1 . > : <biểu thức1> },

      . . .

    }

}

 

Nếu $geoNear1 được đặt bằng customers7, MongoDB sẽ truy vấn tất cả các tài liệu đầu vào

Ví dụ

Gom group order by customers8, đồng thời tính tổng số tiền của từng customers8

1

2

3

4

5

6

7

8

9

db. đơn đặt hàng. tổng hợp([

    {

        $nhóm. {

            _id. "$cust_id",

            tổng. { $tổng. "$amount" }

        }

    }

])

 

=> Kết quả

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

/* 1 */

{

    "_id" . "B456",

    "tổng" . 400

}

 

/* 2 */

{

    "_id" . "C789",

    "tổng" . 800

}

 

/* 3 */

{

    "_id" . "A123",

    "tổng" . 750

}

 


8. orders0

orders0 được sử dụng để phân tách giá trị của một trường mảng trong tài liệu đầu vào. Nếu như trường mảng của một tài liệu đầu vào có N phần tử thì trong đầu ra sẽ có N tài liệu

cú pháp

1

2

{ $thư giãn. <trường đường dẫn> }

 

Ví dụ

Mình sẽ thử áp dụng orders0 với trường mảng orders3 để xem kết quả nó sẽ như thế nào

1

2

3

4

5

6

db. đơn đặt hàng. tổng hợp([

    {

        $thư giãn. "$products"

    }

])

 

=> Kết quả

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

/* 1 */

{

    "_id" . ObjectId("5dfed89743e6fed50628907c"),

    "cust_id" . "A123",

    "sản phẩm" . "quả táo",

    "số tiền" . 500,

    "trạng thái" . "hoàn thành"

}

 

/* 2 */

{

    "_id" . ObjectId("5dfed89743e6fed50628907c"),

    "cust_id" . "A123",

    "sản phẩm" . "chanh",

    "số tiền" . 500,

    "trạng thái" . "hoàn thành"

}

 

/* 3 */

{

    "_id" . ObjectId("5dfed8a643e6fed50628908a"),

    "cust_id" . "B456",

    "sản phẩm" . "chanh",

    "số tiền" . 100,

    "trạng thái" . "đang xử lý"

}

 

/* 4 */

{

    "_id" . ObjectId("5dfed8b043e6fed50628908f"),

    "cust_id" . "B456",

    "sản phẩm" . "quả táo",

    "số tiền" . 300,

    "trạng thái" . "hoàn thành"

}

 

/* 5 */

{

    "_id" . ObjectId("5dfed8b043e6fed50628908f"),

    "cust_id" . "B456",

    "sản phẩm" . "cam",

    "số tiền" . 300,

    "trạng thái" . "hoàn thành"

}

 

/* 6 */

{

    "_id" . ObjectId("5dfed8b943e6fed506289094"),

    "cust_id" . "C789",

    "sản phẩm" . "quả táo",

    "số tiền" . 800,

    "trạng thái" . "hoàn thành"

}

 

/* 7 */

{

    "_id" . ObjectId("5dfed8b943e6fed506289094"),

    "cust_id" . "C789",

    "sản phẩm" . "chanh",

    "số tiền" . 800,

    "trạng thái" . "hoàn thành"

}

 

/* số 8 */

{

    "_id" . ObjectId("5dfed8b943e6fed506289094"),

    "cust_id" . "C789",

    "sản phẩm" . "cam",

    "số tiền" . 800,

    "trạng thái" . "hoàn thành"

}

 

/*9 */

{

    "_id" . ObjectId("5dfed8c343e6fed506289097"),

    "cust_id" . "A123",

    "sản phẩm" . "quả táo",

    "số tiền" . 250,

    "trạng thái" . "hoàn thành"

}

 


9. orders4

orders4 cho phép chúng ta thực hiện một phép nối ngoài trái giữa hai bộ sưu tập trong cùng một cơ sở dữ liệu. Với mỗi tài liệu đầu vào, orders4 sẽ bổ sung một trường mảng chứa các phần tử khớp với bộ sưu tập được tham gia

cú pháp

1

2

3

4

5

6

7

8

9

10

{

   $tra cứu.

     {

       từ. <bộ sưu tập đến join>,

       localField. <trường từthe input documents>,

       foreignField. <trường từthe documents of the "from" collection>,

       như. <đầu ra mảng field>

     }

}

 

in which

  • Bộ sưu tập orders7 could not be shard
  • orders8 có thể có bất kỳ tên nào, nhưng nếu một trường nào đó trong tài liệu đã có tên như vậy thì giá trị của trường đó sẽ bị ghi đè

orders4 tương đương với SQL sau đoạn

1

2

3

4

5

6

<span class="từ khóa mã thông báo"<>SELECT</span> <span class="token operator">*</span><span class="token punctuation">,</span> <span class="token operator">&lt;</span>output array field<span class="token operator">&gt;</span>

<span class="từ khóa mã thông báo"<>FROM</span> collection

<span class="từ khóa mã thông báo"<>WHERE</span> <span class="token operator">&lt;</span>output array field<span class="token operator">&gt;</span> <span class="token operator">IN</span> <span class="token punctuation">(</span><span class="token keyword">SELECT</span> <span class="token operator">*</span>

                               <span class="token keyword">FROM</span> <span class="token operator">&lt;</span>collection <span class="token keyword">to</span> <span class="token keyword">join</span><span class="token operator">&gt;</span>

                               <span class="token keyword">WHERE</span> <span class="token operator">&lt;</span>foreignField<span class="token operator">&gt;=</span> <span class="token operator">&lt;</span>collection<span class="token punctuation">.</span>localField<span class="token operator">&gt;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

 

Ví dụ

Mình sẽ tham gia orderscustomers để bổ sung thêm thông tin của khách hàng trong từng đơn hàng

1

2

3

4

5

6

7

8

9

10

11

db. đơn đặt hàng. tổng hợp([

    {

        $tra cứu. {

            từ. "khách hàng",

            localField. "cust_id",

            foreignField. "_id",

            như. "khách hàng"

        }

    }

])

 

=> Kết quả

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

/* 1 */

{

    "_id" . ObjectId("5dfed89743e6fed50628907c"),

    "cust_id" . "A123",

    "sản phẩm" . [

        "quả táo",

        "chanh"

    ],

    "số tiền" . 500,

    "trạng thái" . "hoàn thành",

    "khách hàng" . [

        {

            "_id" . "A123",

            "tên" . "Alice"

        }

    ]

}

 

/* 2 */

{

    "_id" . ObjectId("5dfed8a643e6fed50628908a"),

    "cust_id" . "B456",

    "sản phẩm" . [

        "chanh"

    ],

    "số tiền" . 100,

    "trạng thái" . "đang xử lý",

    "khách hàng" . []

}

 

/* 3 */

{

    "_id" . ObjectId("5dfed8b043e6fed50628908f"),

    "cust_id" . "B456",

    "sản phẩm" . [

        "quả táo",

        "cam"

    ],

    "số tiền" . 300,

    "trạng thái" . "hoàn thành",

    "khách hàng" . []

}

 

/* 4 */

{

    "_id" . ObjectId("5dfed8b943e6fed506289094"),

    "cust_id" . "C789",

    "sản phẩm" . [

        "quả táo",

        "chanh",

        "cam"

    ],

    "số tiền" . 800,

    "trạng thái" . "hoàn thành",

    "khách hàng" . [

        {

            "_id" . "C789",

            "tên" . "Carol"

        }

    ]

}

 

/* 5 */

{

    "_id" . ObjectId("5dfed8c343e6fed506289097"),

    "cust_id" . "A123",

    "sản phẩm" . [

        "quả táo"

    ],

    "số tiền" . 250,

    "trạng thái" . "hoàn thành",

    "khách hàng" . [

        {

            "_id" . "A123",

            "tên" . "Alice"

        }

    ]

}

 


10. Kết hợp các toán tử tổng hợp

Trong phần này, chúng ta sẽ kết hợp các toán tử tổng hợp trong một đường dẫn. Mình sẽ minh họa thông tin qua 2 ví dụ

Ví dụ 1

Request

  1. Filter all order has customers2 is customers3
  2. Gom group order has been at the bước 1 theo customers8 và tính tổng customers5
  3. Sắp xếp theo tổng số tiền giảm dần

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

db. đơn đặt hàng. tổng hợp([

    {

        $trận đấu. {

            trạng thái. "hoàn thành"

        }

    },

    {

        $nhóm. {

            _id. "$cust_id",

            tổng. { $tổng. "$amount" }

        }

    },

    {

        $sắp xếp. { "tổng". -1 }

    }

])

 

=> Kết quả

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

/* 1 */

{

    "_id" . "C789",

    "tổng" . 800

}

 

/* 2 */

{

    "_id" . "A123",

    "tổng" . 750

}

 

/* 3 */

{

    "_id" . "B456",

    "tổng" . 300

}

 

Ví dụ 2

Tiếp tục ví dụ 1, chúng tôi sẽ bổ sung thêm tên khách hàng cho tài liệu đầu ra. Các bạn lưu ý chúng ta sẽ chỉ bổ sung tên khách hàng mà thôi, còn ID khách hàng thì chúng ta đã lưu trong $geoNear1 rồi