Truy vấn tham gia MongoDB

MongoDB rất thích dữ liệu phi cấu trúc và có vị trí của nó trong bộ công cụ của Nhà phát triển cơ sở dữ liệu. Ngay cả khi đã có chỉ mục, một số thao tác liên quan đến tổng hợp vẫn chậm hơn rất nhiều so với cơ sở dữ liệu quan hệ. Vì vậy, đó là khi sử dụng 'tham gia' giữa các bộ sưu tập. Tra cứu, MongoDB tương đương với Tham gia, chưa thể thực hiện Tham gia hợp nhất hoặc tham gia băm, vì vậy sẽ không bao giờ nhanh ở dạng hiện tại. Nó phù hợp hơn nhiều cho phép liệt kê trong đó có một loạt các lựa chọn thay thế hạn chế. Chúng tôi có thể trợ giúp Tra cứu bằng cách cung cấp một chỉ mục cho phép nó thực hiện nối các vòng lặp lồng nhau trong chỉ mục, nhưng ngoài ra, chúng tôi gặp khó khăn trong việc cải thiện đáng kể hiệu suất của bất kỳ 'THAM GIA' nào

Tất nhiên, chúng ta có thể lập luận rằng các tập hợp tài liệu khiến phép nối trở nên không cần thiết, nhưng điều này chỉ đúng với thông tin tương đối tĩnh, không thay đổi. Dữ liệu có khả năng thay đổi luôn được lưu trữ tốt nhất ở một nơi duy nhất

Bài viết này giải thích cách làm cho cơ sở dữ liệu MongoDB như vậy hoạt động hợp lý khi báo cáo thông tin lịch sử và thông tin thay đổi chậm

Tham gia trong MongoDB

Tại sao phải bận tâm với các phép nối trong cơ sở dữ liệu tài liệu? . Những yêu cầu này rất nhiều tra cứu, đặc biệt là để báo cáo. Một số người tranh luận rằng cơ sở dữ liệu tài liệu nên khử chuẩn hóa dữ liệu để loại bỏ yêu cầu tra cứu. Tôi sẽ lập luận rằng, nếu bạn cung cấp và duy trì các bộ sưu tập tóm tắt, được gọi là tổng hợp hoặc tổng hợp trước và bạn sử dụng một chuỗi tách biệt với ứng dụng để duy trì chúng khi dữ liệu trong bảng thay đổi, thì nó . Đó là cơ sở dữ liệu tương đương với việc nấu bữa ăn trước trong bếp thay vì yêu cầu mỗi khách tự nấu bữa ăn tại bàn

Giống như một chiếc giường thử nghiệm, chúng tôi sẽ sử dụng chuyển đổi sang MongoDB của cơ sở dữ liệu thực hành cổ điển của SQL Server, AdventureWorks. Tôi chọn điều này vì bạn cần thực hiện một số tra cứu để nhận báo cáo từ nó và nó có thể dẫn đến một số sự cố di chuyển khó xử, hữu ích cho mục đích của chúng tôi. Nó cũng cho phép chúng tôi thực hiện so sánh trực tiếp hai hệ thống cơ sở dữ liệu, mặc dù chúng tôi làm điều này với những cảnh báo thích hợp rằng nó giống như so sánh táo và mèo con. Tôi bao gồm JSON mở rộng cho cơ sở dữ liệu này với bài viết. Chỉ mất một chút thời gian để tải

Truy vấn không có chỉ mục

Ví dụ của chúng tôi, chúng tôi sẽ bắt đầu mà không có bất kỳ chỉ mục nào và sau đó thêm chúng sau, đảm bảo rằng chúng đang được sử dụng bằng cách kiểm tra thời gian. Chúng tôi cũng sẽ sử dụng trình lược tả MongoDB để kiểm tra chiến lược đang được sử dụng

Chúng tôi thực hiện truy vấn SQL sau trong MongoDB bằng Studio 3T, GUI MongoDB với tính năng Truy vấn SQL tiện dụng

1

2

3

4

5

6

7

8

9

CHỌN p. Loại người, Tổng[soh . .TotalDue], Số lượng[*]

  TỪ " Doanh số. SalesOrderHeader " soh

    INNER THAM GIA " Bán hàng.Khách hàng " c

      BẬT soh. ID khách hàng = c. ID khách hàng

    NGƯỜI THAM GIA " Người.Người " p

      BẬT c. PersonID = p. ID doanh nghiệp

  NHÓM BỞI p. Kiểu người

--Loại người chính. SC = Liên hệ cửa hàng,

--IN = Khách hàng cá nhân [bán lẻ]

Nó cung cấp kết quả cho chúng tôi biết số lượng khách hàng cá nhân và địa chỉ liên hệ của cửa hàng cũng như tổng giá trị đơn đặt hàng của họ. Thay đổi duy nhất của chúng tôi từ SQL Server là đặt các dấu phân cách chuỗi xung quanh tên của bộ sưu tập

Nó có hai phép nối, được thực hiện bằng cách tra cứu. Chúng tôi nhấn nút. Năm phút mười bảy giây sau, nó kết thúc. Ngay sau đó, một người có liên quan nhưng hay trách móc điện thoại từ Hiệp hội Phòng chống Hành vi Đối xử Tàn ác đối với Cơ sở Dữ liệu. Cô ấy chỉ ra rằng một vài chỉ số sẽ giúp giảm bớt rất nhiều đau khổ. [Phương thức con trỏ con trỏ. maxTimeMS[] chỉ hoạt động với truy vấn]

Tốt nhất là xem mã được tạo tự động vào thời điểm này

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

// Yêu cầu MongoShell 3 chính thức. 6+

sử dụng AdventureWorks;

db. getCollection["Doanh số. SalesOrderHeader"]. tổng hợp[

    [

        {

            "$project" . {

                "_id" . SốInt[0],

                "soh" . "$$ROOT"

            }

        },

        {

            "$lookup" . {

                "localField" . "soh. ID khách hàng",

                "từ" . "Bán hàng. Khách hàng",

                "lĩnh vực nước ngoài" . "_id",

                "là" . "c"

            }

        },

        {

            "$unwind" . {

                "đường dẫn" . "$c",

                "preserveNullAndEmptyArrays" . sai

            }

        },

        {

            "$lookup" . {

                "localField" . "c. PersonID",

                "từ" . "Người. Người",

                "lĩnh vực nước ngoài" . "BusinessEntityID",

                "là" . "p"

            }

        },

        {

            "$unwind" . {

                "đường dẫn" . "$p",

                "preserveNullAndEmptyArrays" . sai

            }

        },

        {

            "$group" . {

                "_id" . {

                    "p᎐PersonType" . "$p. Loại Người"

                },

                "SUM[soh᎐TotalDue]" . {

                    "$sum" . "$soh. Tổng cộng"

                },

                "COUNT[*]" . {

                    "$sum" . SốInt[1]

                }

            }

        },

        {

            "$project" . {

                "p. PersonType" . "$_id. p᎐PersonType",

                "SUM[soh᎐TotalDue]" . "$SUM[soh᎐TotalDue]",

                "COUNT[*]" . "$COUNT[*]",

                "_id" . SốInt[0]

            }

        }

    ],

    {

        "allowDiskUse" . đúng

    }

];

Khi bạn thực hiện tra cứu trong MongoDB, trường khóa mà bạn chỉ định trong giai đoạn tổng hợp là trường của các tài liệu trong bộ sưu tập mà bạn đang tra cứu. Trường này xác định các tài liệu mà bạn sẽ thu thập dưới dạng một mảng tài liệu

Quá trình $lookup khớp trường nước ngoài với trường địa phương từ các tài liệu đầu vào đi xuống đường ống dẫn

Trường khóa đó có thể không tồn tại trong tài liệu được tham chiếu, trong trường hợp đó, nó được coi là không có giá trị. Nếu bạn không có chỉ mục trên trường nước ngoài, nó sẽ thực hiện truy vấn quét bộ sưu tập đầy đủ [COLLSCAN] cho từng tài liệu trong đường dẫn. Điều này trở nên đắt đỏ. chúng tôi cần số lần truy cập chỉ mục thay vì quét bảng

Một lưu ý về các chỉ số

Nếu bạn chỉ cần tìm nạp một vài trường từ một bộ sưu tập, thì sẽ hiệu quả hơn nhiều nếu bao gồm các trường này với tiêu chí truy vấn thực tế trong một 'chỉ mục bao hàm'. Điều này cho phép MongoDB sử dụng chiến lược nhanh hơn để trả về kết quả trực tiếp từ chỉ mục mà không cần phải truy cập tài liệu. Thật hợp lý khi làm điều này với bất kỳ truy vấn nào có khả năng được thực hiện thường xuyên

Những lĩnh vực nào nên có một chỉ mục?

  • Bất kỳ trường 'khóa' nào được sử dụng trong tra cứu hoặc tìm kiếm để xác định một tài liệu cụ thể
  • Các trường được sử dụng làm khóa ngoại
  • Trong trường hợp khóa sử dụng một số trường, chẳng hạn như kết hợp Tên/Họ, thì tốt nhất nên sử dụng chỉ mục ghép
  • Trường hợp một hoặc nhiều trường được sử dụng để sắp xếp

Bạn nên xem xét cách bạn muốn sắp xếp được thực hiện trong các báo cáo, bởi vì điều này xác định thứ tự tốt nhất cho các trường trong chỉ mục

Tạo chỉ mục

Bất cứ khi nào các bảng quan hệ có một cột duy nhất làm khóa chính, chúng tôi đã thêm chúng dưới dạng trường _id như một phần của quá trình nhập. Các trường _id đặc biệt này hoạt động rất giống với các chỉ mục được nhóm. Chúng ta phải gọi chúng là _id để chúng được chấp nhận làm chỉ mục nhóm. Chúng tôi đã thêm trường ban đầu dưới tên ban đầu của nó để các truy vấn không bị hỏng. Chúng ta chỉ cần tạo một chỉ mục cho tất cả các trường khác được sử dụng để tra cứu; . Điều này tương đương với những gì được chỉ định trong mệnh đề ON của THAM GIA. Trong trường hợp này, điều đó có nghĩa là Bán hàng. khách hàng. PersonID, Người. Người. BusinessEntityID và Bán hàng. Tiêu Đề Đơn Đặt Hàng. ID khách hàng. Chúng tôi thay đổi tham chiếu khóa chính thành Bán hàng. khách hàng. CustomerID để sử dụng _id đã được lập chỉ mục của chúng tôi, có cùng giá trị với customer_id

Chúng tôi kiểm tra lại và phản hồi giảm xuống còn 6. 6 giây Tốt hơn so với 5 phút 17 giây không có chỉ mục, nhưng còn lâu mới đạt được những gì cơ sở dữ liệu SQL Server ban đầu có thể làm. Trên cùng một máy chủ với MongoDB, SQL Server quản lý cùng một tập hợp trong 160 mili giây

Đáng buồn thay, trình cấu hình MongoDB không thể cho chúng tôi biết nhiều điều để giúp đỡ, ngoài việc cho chúng tôi biết rằng một COLLSCAN đã được sử dụng. Điều này là không thể tránh khỏi bởi vì, mặc dù các tra cứu riêng lẻ đã lặng lẽ sử dụng một chỉ mục, một chỉ mục không thể dễ dàng được sử dụng như một phần của tập hợp tổng thể trừ khi nó có giai đoạn khớp ban đầu

Nếu chúng ta thay đổi thứ tự của phép nối trong truy vấn SQL trong Studio 3T, thì SQL Server sẽ thực thi chính xác kế hoạch giống như trước đây, đó là thực hiện phép nối bên trong đối sánh hàm băm trên bảng khách hàng và bảng người, sử dụng quét chỉ mục nhóm trên cả hai bảng, theo sau

Đây là phiên bản Studio 3T

1

2

3

4

5

6

7

8

9

CHỌN p. Loại người, Tổng[soh . .TotalDue], Số lượng[*]

TỪ " Doanh số. Khách hàng " c

    NGƯỜI THAM GIA " Người.Người " p

      BẬT c. PersonID = p. ID doanh nghiệp

    NGƯỜI NHẬP THAM GIA   " Sales.SalesOrderHeader " soh

      BẬT soh. ID khách hàng = c. ID khách hàng

  NHÓM BỞI p. Kiểu người

--Loại người chính. SC = Liên hệ cửa hàng,

--IN = Khách hàng cá nhân [bán lẻ]

Trong Studio 3T, thứ tự tổng hợp phản ánh thứ tự của các phép nối, vì vậy thứ tự thực hiện sẽ khác và tốt hơn ở 4. 2 giây. Việc tối ưu hóa tập lệnh tổng hợp trong Trình chỉnh sửa tập hợp tạo ra một chút khác biệt đối với điều này, rút ​​ngắn thời gian xuống chỉ còn hơn ba giây. Về cơ bản, các tối ưu hóa chỉ bao gồm việc giảm các trường được đưa qua đường ống xuống chỉ còn các trường thiết yếu

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

// Yêu cầu MongoShell 3 chính thức. 6+

sử dụng AdventureWorks2016;

db. getCollection["Doanh số. Khách hàng"]. tổng hợp[

    [

        {

            "$project" . {

                "_id" . SốInt[0],

                "ID khách hàng" . 1. 0,

                "PersonID" . 1. 0

            }

        },

        {

            "$lookup" . {

                "localField" . "PersonID",

                "từ" . "Người. Người",

                "lĩnh vực nước ngoài" . "BusinessEntityID",

                "là" . "p"

            }

        },

        {

            "$unwind" . {

                "đường dẫn" . "$p",

                "preserveNullAndEmptyArrays" . sai

            }

        },

        {

            "$project" . {

                "ID khách hàng" . 1. 0,

                "PersonID" . 1. 0,

                "Loại người" . "$p. Loại Người"

            }

        },

        {

            "$lookup" . {

                "localField" . "ID khách hàng",

                "từ" . "Bán hàng. SalesOrderHeader",

                "lĩnh vực nước ngoài" . "ID khách hàng",

                "là" . "soh"

            }

        },

        {

            "$unwind" . {

                "đường dẫn" . "$soh",

                "preserveNullAndEmptyArrays" . sai

            }

        },

        {

            "$project" . {

                "ID khách hàng" . 1. 0,

                "PersonID" . 1. 0,

                "Loại người" . 1. 0,

                "TotalDue" . "$soh. Tổng cộng"

            }

        },

        {

            "$group" . {

                "_id" . {

                    "Loại người" . "$PersonType"

                },

                "SUM[TotalDue]" . {

                    "$sum" . "$TotalDue"

                },

                "COUNT[*]" . {

                    "$sum" . SốInt[1]

                }

            }

        },

        {

            "$project" . {

                "Loại người" . "$_id. PersonType",

                "Tổng" . "$SUM[TotalDue]",

                "Giao dịch" . "$COUNT[*]",

                "_id" . SốInt[0]

            }

        }

    ],

    {

        "allowDiskUse" . sai

    }

];

Nếu chúng tôi tiếp tục đi theo con đường này, điều đó có nghĩa là chúng tôi dành nhiều thời gian để tối ưu hóa từng truy vấn. Chúng ta cần tưởng tượng rằng có những người quản lý đang huy động chúng ta để lấy cả đống báo cáo doanh thu. Thay vào đó chúng ta nên làm gì?

Sử dụng bộ sưu tập tổng hợp trước để đơn giản hóa báo cáo

Bạn nên tạo một bộ sưu tập tổng hợp ở mức độ chi tiết thấp nhất mà bạn có khả năng báo cáo. Điều này tương đương với một khối OLAP. Trong trường hợp này, chúng tôi đang xử lý các bản ghi giao dịch lấy từ hóa đơn. Những điều này không thay đổi và có những lý do chính đáng tại sao chúng không nên thay đổi. Tôi luôn ngạc nhiên khi thấy dữ liệu lịch sử được tìm nạp và tổng hợp mỗi khi có báo cáo. Sẽ chỉ có ý nghĩa nếu có những người du hành thời gian đột nhiên từ chối trả lại xe đạp của họ [trong trường hợp ví dụ của chúng tôi, AdventureWorks] hoặc bạn đang báo cáo về dữ liệu của Enron. Trong MongoDB, chúng tôi chỉ cần chuẩn bị và duy trì dữ liệu lịch sử của mình ở dạng 'được nấu sẵn'

Nếu chúng tôi tổng hợp trước với một bộ sưu tập trung gian như thế này…

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

// Yêu cầu chính thức MongoShell 3.6+

sử dụng AdventureWorks2016;

db. getCollection[ " Doanh số. Khách hàng " ]. tổng hợp[

    [

        {

             " $dự án " : {

                         " _id " . SốInt[0],

                         " ID khách hàng " . 1. 0,

                         " PersonID " . 1. 0

            }

        },

        {

             " $tra cứu " : {

                         " localField " . " ID cá nhân " ,

                         " từ " . " Người. Người " ,

                 " lĩnh vực nước ngoài " . " ID Doanh nghiệp " ,

                 " như " . " p "

            }

        },

        {

             " $thư giãn " : {

                 " đường dẫn " . " $p " ,

                         " preserveNullAndEmptyArrays " . sai

            }

        },

        {

             " $dự án " : {

                         " ID khách hàng " . 1. 0,

                         " PersonID " . 1. 0,

                         " Loại người " . " $p. Kiểu người "

            }

        },

        {

             " $tra cứu " : {

                         " localField " . " ID khách hàng " ,

                         " từ " . " Doanh số. SalesOrderHeader " ,

                 " lĩnh vực nước ngoài " . " ID khách hàng " ,

                 " như " . " soh "

            }

        },

        {

             " $thư giãn " : {

                 " đường dẫn " . " $soh " ,

                         " preserveNullAndEmptyArrays " . sai

            }

        },

        {

             " $dự án " : {

                         " ID khách hàng " . 1. 0,

                         " PersonID " . 1. 0,

                         " Loại người " . 1. 0,

                 " Tổng số tiền đến hạn " . " $soh. TotalDue "

            }

        },

        {

             " $nhóm " : {

                         " _id " . {

                     " Kiểu người " . " $Kiểu người "

                },

                         " SUM[Tổng đến hạn]" : {

                     " $tổng " : " $TotalDue "

                },

                         " ĐẾM[*]" : {

                     " $tổng " : SốInt[1]

                }

            }

        },

        {

             " $dự án " : {

                         " Loại người " . " $_id. Kiểu người " ,

                 " Tổng " . " $SUM[TotalDue]",

                 " Giao dịch " . " $ĐẾM[*]",

                         " _id " . SốInt[0]

            }

        }

    ],

    {

         " cho phép DiskUse " . sai

    }

];

… sau đó báo cáo của chúng tôi giảm từ 4. 2 giây đến 25 mili giây

Trong thực tế, tôi không muốn lưu trữ một bộ sưu tập tổng hợp chuyên dụng như vậy. Tôi sẽ cắt báo cáo tổng quát hơn theo khoảng thời gian chẳng hạn như tuần, tháng hoặc năm để sau đó bạn có thể lập biểu đồ bán hàng trong một khoảng thời gian. Tôi cũng sẽ thêm ID của người bán hàng và ID của cửa hàng để ai đó nhận được tín dụng cho việc bán hàng

Ngay cả với các trường bổ sung và nhiều tài liệu hơn, bạn vẫn sẽ ở cùng một vùng hiệu suất trong việc tạo tập hợp. Nếu bạn sử dụng kỹ thuật này, bạn phải duy trì các khối hoặc bộ sưu tập tổng hợp, theo cách giống như khối OLAP bất cứ khi nào dữ liệu thay đổi. Điều này phải được thực hiện như một công việc theo lịch trình trong nền. Thay vào đó, nếu nó được thực hiện như một phần của phiên người dùng bất cứ khi nào tập hợp được phát hiện là lỗi thời, thì bạn có thể gây tắc nghẽn, đặc biệt nếu kết nối được chia sẻ

Bởi vì tôi có xu hướng suy nghĩ bằng SQL, tôi sẽ phác thảo tổng hợp mà tôi muốn. Vì SQL nhất thiết phải bị giới hạn trong những gì nó có thể làm, nên tôi bỏ qua những thứ như tính toán ngày tháng và giai đoạn đầu ra

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

CHỌN c. PersonID, p. Kiểu người, soh. ID người bán hàng, psp. Tên, psp. Mã vùng quốc gia,

  Tổng[soh. TotalDue], Count[*]

  --,

  --Năm[soh. OrderDate] AS năm, tháng[soh. OrderDate] NHƯ tháng,

  --NgàyPhần[TUẦN, soh. OrderDate] NHƯ tuần

  TỪ " Doanh số. SalesOrderHeader " AS soh

    INNER THAM GIA " Bán hàng.Khách hàng " NHƯ c

      BẬT c. ID khách hàng = soh. ID khách hàng

    NGƯỜI THAM GIA " Người.Người " NHƯ p

      BẬT p. BusinessEntityID = c. ID cá nhân

    NGƯỜI TRONG THAM GIA " Người.Địa chỉ " AS pa

      BẬT pa. ID địa chỉ = soh. BillToAddressID

    NGƯỜI THAM GIA " Người.Tiểu bangTỉnh " AS psp

      BẬT psp. ID tỉnh bang = pa. ID tỉnh bang

  NHÓM BỞI c. PersonID, p. Loại người, soh. ID người bán hàng, psp. Tên,

  psp. Mã vùng quốc gia

  --, Năm[soh. OrderDate], Tháng[soh. Ngày đặt hàng],

  --NgàyPhần[TUẦN, soh. OrderDate];

Nhận đúng thứ tự và buộc chặt các kết thúc lỏng lẻo

Khi điều này đang chạy, tôi sao chép mã truy vấn shell mongo và dán nó vào Trình chỉnh sửa tập hợp, trình tạo truy vấn tập hợp MongoDB của Studio 3T

Sau đó tôi tinh chỉnh tập hợp

Khi điều này được thực thi, sau đó tôi có thể thực hiện các báo cáo trực tiếp từ tab Truy vấn SQL của Studio 3T

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

--tổng giá trị hóa đơn mỗi năm cho AdventureWorks

Chọn Năm, tổng[Total]

  từ " Doanh số. Tổng hợp "

  nhóm theo Năm

  đặt hàng theo Năm asc

  

--tổng giá trị hóa đơn mỗi năm cho mỗi quốc gia

--cho AdventureWorks

Chọn Năm, Mã vùng quốc gia, sum[Total]

  từ " Doanh số. Tổng hợp "

  nhóm theo Năm,CountryRegionCode

  đặt hàng bởi  Mã vùng quốc gia  

  

--Hai mươi địa điểm hàng đầu để mua hàng từ các công trình phiêu lưu

Chọn Tên,tổng[Total],sum[invoices]

  từ " Doanh số. Tổng hợp "

  nhóm bởi Tên

  đặt hàng theo tổng[Total] desc

  giới hạn 20  

--Top 20 người bán hàng

Chọn pp. Tên,pp. Họ,tổng[sa . .Tổng],tổng[ . sa.hóa đơn]

từ " Người. Người " pp

bên trong tham gia " Bán hàng. Tổng hợp " sa

bật pp. BusinessEntityID=sa. ID người bán hàng

nhóm bởi pp. Tên,pp. Họ,sa. ID người bán hàng

  đặt hàng theo tổng[sa.Tổng] mô tả

  giới hạn 20  

  --20 khách hàng hàng đầu

Chọn pp. Tên,pp. Họ,tổng[sa . .Tổng],tổng[ . sa.hóa đơn]

từ " Người. Người " pp

bên trong tham gia " Bán hàng. Tổng hợp " sa

bật pp. BusinessEntityID=sa. ID cá nhân

nhóm bởi pp. Tên,pp. Họ,sa. ID cá nhân

  đặt hàng theo tổng[sa.Tổng] mô tả

  giới hạn 20  

… và vân vân

Cái cuối cùng đó là một ví dụ trong đó trả tiền để làm lại mã dưới dạng đường dẫn tổng hợp MongoDB

Tập hợp đầy đủ mà bạn có thể xem bằng ngôn ngữ shell mongo thông qua Mã truy vấn, như sau

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

sử dụng AdventureWorks2016;

db. getCollection["Doanh số. tổng hợp"]. tổng hợp[

    [

        {

            "$group" . {

                "_id" . {

                    "PersonID" . "$PersonID"

                },

                "Tổng" . {

                    "$sum" . "$Total"

                },

                "Hóa đơn" . {

                    "$sum" . "$Hóa đơn"

                }

            }

        },

        {

            "$project" . {

                "Tổng" . 1. 0,

                "Hóa đơn" . 1. 0,

                "PersonID" . "$_id. PersonID",

                "_id" . SốInt[0]

            }

        },

        {

            "$sort" . {

                "Tổng" . SốInt[-1]

            }

        },

        {

            "$limit" . SốInt[20]

        },

        {

            "$lookup" . {

                "localField" . "PersonID",

                "từ" . "Người. Người",

                "lĩnh vực nước ngoài" . "BusinessEntityID",

                "là" . "p"

            }

        },

        {

            "$unwind" . {

                "đường dẫn" . "$p",

                "preserveNullAndEmptyArrays" . sai

            }

        },

        {

            "$project" . {

                "Khách hàng" . {

                    "$concat" . [

                        "$p. Tiêu đề",

                        " ",

                        "$p. FirstName",

                        {

                            "$ifNull" . [

                                    {

                                    "$concat" . [

                                             " ",

                                             "$p. Tên đệm"

                                    ]

                                    },

                                    ""

                            ]

                        },

                        " ",

                        "$p. Họ"

                    ]

                },

                "Tổng" . 1. 0,

                "Hóa đơn" . 1. 0

            }

        }

    ],

    {

        "allowDiskUse" . sai

    }

];

Điều này thực hiện tổng hợp trong 120 mili giây trên máy của tôi, khi bạn xem xét các bước liên quan, nó khá tốt. Nó giảm từ 4 giây trong phiên bản được tạo từ mã SQL đó

Điều tương tự cũng áp dụng cho báo cáo nhân viên bán hàng. Chúng tôi tạo điều này rất nhanh bằng cách thêm từ 'bán hàng' vào nhóm ban đầu

Điều này thậm chí còn nhanh hơn [48 mili giây] vì trước tiên chúng ta có thể loại bỏ tất cả các bản ghi với nhân viên bán hàng $null [khách hàng đặt hàng qua thư]

Mẹo ở đây là thực hiện thao tác tra cứu tốn kém trên càng ít tài liệu càng tốt

Những gì chúng tôi làm là

  1. Loại bỏ tất cả null [trong trường hợp của nhân viên bán hàng]
  2. Thực hiện nhóm trên person_ID trước, sau đó
  3. Chỉ sắp xếp ra 20 khách hàng hàng đầu

Chỉ khi đầu ra giảm xuống càng ít tài liệu càng tốt, chúng tôi mới thực hiện tra cứu. Bởi vì hoạt động chỉ được thực hiện một vài lần, chúng tôi có thể đủ khả năng để tạo ra tên khách hàng đúng cách

kết luận

Bằng thủ công, mưu mẹo và sự khéo léo, chúng tôi có thể giảm một truy vấn từ hơn năm phút xuống còn khoảng 100 mili giây. Để vượt qua nỗi tuyệt vọng ban đầu về số phút chờ đợi, chúng ta chỉ cần thêm các chỉ mục thông thường vào các tham chiếu và khóa khóa ngoại, đồng thời thử các chỉ mục bao phủ và giao nhau

Rõ ràng là bạn nên kiểm tra xem liệu bạn có đang quét đi quét lại dữ liệu lịch sử hoặc dữ liệu không thay đổi một cách không cần thiết hay không. Đây là một sai lầm phổ biến đến nỗi nó gần như là đặc hữu

Trong bài viết này, tôi đã minh họa cách một 'khối lập phương' có thể tăng tốc độ tạo và sản xuất rất nhiều báo cáo lấy thông tin từ cùng một dữ liệu cơ bản

Cuối cùng, điều quan trọng là phải sắp xếp thứ tự của các giai đoạn trong một quy trình tổng hợp theo đúng thứ tự. Việc tra cứu, chẳng hạn như sắp xếp, nên được hoãn lại cho đến khi bạn chỉ có những tài liệu cần thiết cho báo cáo cuối cùng. So sánh và dự đoán nên được thực hiện sớm. Điểm mà bạn thực hiện nhóm là một quyết định mang tính chiến thuật hơn, nhưng đó không phải là một hoạt động đặc biệt chậm trong MongoDB. Điều hợp lý là giữ cho quy trình gọn gàng, chỉ đẩy dữ liệu bạn cần trong mỗi tài liệu khi nó đi qua quy trình, nhưng tốt nhất bạn nên xem đây là một phần của quá trình dọn dẹp cuối cùng và mặc dù nó sẽ tăng tốc mọi thứ, nhưng nó không'

Tất nhiên, thông tin giao dịch hiện tại không bao giờ có thể được xử lý theo cách này. bạn sẽ không bao giờ muốn thông tin lỗi thời về giao dịch hiện tại, chẳng hạn. Tuy nhiên, đây là khối lượng tương đối nhỏ và ít có khả năng xuất hiện dưới dạng sự cố khi tra cứu

Các tệp JSON mở rộng cho phiên bản MongoDB của AdventureWorks có tại đây

Dennes Torres 23 tháng một 2023

Dennes Torres 23 tháng một 2023

Chức năng Azure và danh tính được quản lý. Bí mật khác

3

  • Blog

Tôi đã viết về Bí mật danh tính được quản lý vài tuần trước, nhưng kể từ khi bài báo đó được xuất bản, tôi đã có những khám phá thú vị mới để bổ sung thêm cho những bí mật này. Sự kết hợp của các khả năng là đáng kể và tôi phải đối mặt với hai tình huống mới mà tôi chưa từng gặp phải trước đây. Hãy khám phá những bí mật mới. Tài khoản lưu trữ và trình kích hoạt Lưu trữ … Đọc thêm

Làm cách nào để viết truy vấn nối bên trong trong MongoDB?

Làm cách nào để thực hiện thao tác Tham gia bên trong MongoDB? .
từ. Tên của bộ sưu tập sẽ được tham gia
localField và ForeignField. Để tham gia các bộ sưu tập bằng cách sử dụng $lookup, bắt buộc phải có trường từ cả hai bộ sưu tập. .
như. Kết nối giữa hai bộ sưu tập trong một kết quả

Tại sao phép nối không được sử dụng trong MongoDB?

Trong MongoDB, một mẫu phổ biến là nhúng. Trong quan hệ khi bình thường hóa mọi thứ bị chia thành nhiều phần. Thông thường trong mongo, các phần này kết thúc bằng một tài liệu duy nhất , vì vậy dù sao cũng không cần tham gia.

Thuật ngữ được sử dụng để tham gia trong MongoDB là gì?

Bạn có thể tham gia hai bộ sưu tập trong Mongodb bằng cách sử dụng tra cứu được cung cấp trong 3. 2 phiên bản. Trong trường hợp của bạn, truy vấn sẽ là db. bình luận

Làm cách nào để lấy dữ liệu từ các bộ sưu tập khác nhau trong MongoDB?

Sau khi có mô hình, chúng ta có thể sử dụng phương thức find[] trên mô hình của một bộ sưu tập cụ thể để lấy tài liệu của bộ sưu tập .

Chủ Đề