Điều cần nhớ là MongoDB sử dụng cách tiếp cận "NoSQL" để lưu trữ dữ liệu, vì vậy hãy loại bỏ suy nghĩ về các lựa chọn, tham gia, v.v. từ tâm trí của bạn. Cách nó lưu trữ dữ liệu của bạn ở dạng tài liệu và bộ sưu tập, cho phép một phương tiện động để thêm và lấy dữ liệu từ các vị trí lưu trữ của bạn
Điều đó đang được nói, để hiểu khái niệm đằng sau tham số $unwind, trước tiên bạn phải hiểu trường hợp sử dụng mà bạn đang cố gắng trích dẫn đang nói gì. Tài liệu ví dụ từ mongodb. tổ chức như sau
{ title : "this is my title" , author : "bob" , posted : new Date () , pageViews : 5 , tags : [ "fun" , "good" , "fun" ] , comments : [ { author :"joe" , text : "this is cool" } , { author :"sam" , text : "this is bad" } ], other : { foo : 5 } }Lưu ý cách các thẻ thực sự là một mảng gồm 3 mục, trong trường hợp này là "vui vẻ", "tốt" và "vui vẻ"
Những gì $unwind làm là cho phép bạn bóc một tài liệu cho từng phần tử và trả về tài liệu kết quả đó. Để nghĩ về điều này theo cách tiếp cận cổ điển, nó sẽ tương đương với "đối với mỗi mục trong mảng thẻ, hãy trả về một tài liệu chỉ có mục đó"
Do đó, kết quả của việc chạy như sau
db.article.aggregate( { $project : { author : 1 , title : 1 , tags : 1 }}, { $unwind : "$tags" } );sẽ trả lại các tài liệu sau
{ "result" : [ { "_id" : ObjectId("4e6e4ef557b77501a49233f6"), "title" : "this is my title", "author" : "bob", "tags" : "fun" }, { "_id" : ObjectId("4e6e4ef557b77501a49233f6"), "title" : "this is my title", "author" : "bob", "tags" : "good" }, { "_id" : ObjectId("4e6e4ef557b77501a49233f6"), "title" : "this is my title", "author" : "bob", "tags" : "fun" } ], "OK" : 1 }Lưu ý rằng điều duy nhất thay đổi trong mảng kết quả là những gì đang được trả về trong giá trị thẻ. Nếu bạn cần một tài liệu tham khảo bổ sung về cách thức hoạt động của nó, tôi đã bao gồm một liên kết ở đây
MongoDB $unwind là một công cụ hữu ích trong việc thực hiện tổng hợp trong MongoDB. Hãy xem $unwind và cách sử dụng nó
(Bài viết này là một phần của Hướng dẫn MongoDB của chúng tôi. Sử dụng menu bên phải để điều hướng. )
MongoDB $unwind là gì?
Toán tử MongoDB $unwind được sử dụng để giải cấu trúc một trường mảng trong tài liệu và tạo các tài liệu đầu ra riêng biệt cho từng mục trong mảng
Sự khác biệt duy nhất giữa tài liệu đầu vào và tài liệu đầu ra là, trong tài liệu đầu ra, giá trị của trường mảng được thay thế bằng một mục duy nhất từ mảng tài liệu đầu vào. Bạn sẽ thấy điều này khi tôi hướng dẫn bạn qua ví dụ này
MongoDB $unwind chuyển đổi các tài liệu phức tạp thành các tài liệu đơn giản hơn, giúp tăng khả năng đọc và hiểu. Điều này cũng cho phép chúng tôi thực hiện các hoạt động bổ sung, như nhóm và sắp xếp trên kết quả đầu ra
Cú pháp cơ bản của toán tử $unwind
{ $unwind: "$<field path/ array path>" }{$unwind: { path : "$<field path/ array path>", <optional arguments>}}Tại đây, bạn nên thêm tiền tố vào đường dẫn bằng ký hiệu đô la “$” để thao tác $unwind thành công
Tiếp theo, chúng tôi sẽ minh họa thao tác $unwind đơn giản bằng cách sử dụng bộ sưu tập “vehicledetails” của chúng tôi. Đầu tiên, hãy xem qua bộ sưu tập của chúng tôi
db.vehicledetails.find().pretty()Kết quả
Tiếp theo, chúng tôi sử dụng toán tử $unwind để giải cấu trúc trường mảng “model_year” và tạo các tài liệu riêng cho từng năm
db.vehicledetails.aggregate([{$unwind : "$model_year" }]).pretty()Kết quả
Như thể hiện trong đầu ra ở trên, một tài liệu mới được tạo cho mỗi mục trong mảng “model_year”
Cách $unwind hoạt động với các đường dẫn trường không phải mảng
Trước MongoDB 3. 2, nếu một trường không phải mảng được định nghĩa là đường dẫn trong toán tử $unwind, nó sẽ dẫn đến lỗi. Từ MongoDB 3. 2 trở đi, bất kỳ trường không phải mảng nào không phân giải thành mảng bị thiếu, null hoặc trống sẽ được coi là một mảng phần tử đơn lẻ
Ví dụ tiếp theo này cho thấy cách toán tử $unwind xử lý một mảng phần tử đơn lẻ
db.vehicledetails.aggregate([{$unwind : "$make" }]).pretty()Kết quả
Ở đây, thao tác $unwind đã tạo thành công một tài liệu đầu ra vì nó coi trường “make” là một mảng mục duy nhất
Thiếu trường dưới dạng đường dẫn
Toán tử $unwind sẽ không tạo bất kỳ đầu ra nào nếu đường dẫn đã chỉ định là trường bị thiếu/không khả dụng. Sẽ không có lỗi vì $unwind sẽ bỏ qua tài liệu đầu vào
________số 8_______Kết quả
Trong thao tác trên, đường dẫn được cung cấp cho toán tử $unwind là trường “use”. Tuy nhiên, tài liệu đầu vào bị bỏ qua vì không có trường "sử dụng" trong tài liệu đầu vào
tùy chọn toán tử $unwind
Toán tử $unwind có thể được sử dụng với hai đối số tùy chọn, đó là includeArrayIndex vàserveNullAndEmptyArrays. Phần này sẽ chứng minh mỗi tùy chọn ảnh hưởng như thế nào đến kết quả của thao tác $unwind
Một lần nữa, chúng ta sẽ sử dụng bộ sưu tập “vehicledetails” với các tài liệu bổ sung để chứng minh chức năng của các đối số tùy chọn
db.vehicledetails.find().pretty()Kết quả
Khi bạn thực hiện thao tác $unwind trên tập dữ liệu trên với trường “model_year”, đầu ra sẽ bao gồm năm kết quả
Hãy xem điều này trong ví dụ này
db.vehicledetails.aggregate([{$unwind : "$model_year" }]).pretty()Kết quả
tùy chọn bao gồmArray Index
Tùy chọn bao gồmArrayIndex được sử dụng để lấy chỉ mục mảng với đầu ra hoạt động $unwind. Chúng ta có thể định nghĩa một trường theo cú pháp “includeArrayIndex” để lấy chỉ mục mảng của từng tài liệu đầu ra. Nếu trường mảng là null, điều này sẽ dẫn đến giá trị null trong trường do người dùng xác định và nếu có một mảng trống, nó sẽ bị bỏ qua vì không có mục nào trong mảng đó
Trong ví dụ dưới đây, trường “model_year” được sử dụng để thực hiện thao tác $unwind và trường “vehicleIndex” do người dùng xác định được sử dụng để lấy chỉ mục mảng
db.vehicledetails.aggregate([{$unwind : {path: "$model_year", includeArrayIndex: "vehicleIndex" }}]).pretty()Kết quả
tùy chọn bảo tồnNullAndEmptyArrays
Việc xác định tùy chọn “preserveNullAndEmptyArrays” trong thao tác $unwind cho phép người dùng bao gồm các tài liệu trong đó trường mảng bị thiếu, null hoặc một mảng trống. Tùy chọn “preserveNullAndEmptyArrays” chỉ nhận các đối số Boolean như true hoặc false
Hãy sử dụng các tài liệu trong bộ sưu tập “vehicledetails” để chứng minh tùy chọn “preserveNullAndEmptyArrays”. Điều này sẽ dẫn đến kết quả đầu ra trong đó tất cả các mảng bị thiếu, không có giá trị hoặc trống trong trường “model_year” đều được ghi lại
db.vehicledetails.aggregate([{$unwind : {path: "$model_year", preserveNullAndEmptyArrays: true}}]).pretty()Kết quả
Nhóm dữ liệu theo giá trị Unwound
Trong MongoDB, bạn có thể sử dụng tập dữ liệu kết quả của thao tác $unwind—các giá trị không kết nối—để tiếp tục chuyển đổi tập dữ liệu
Bộ sưu tập “vehiclesalesmain” được sử dụng để minh họa cách kết hợp toán tử $unwind với các hàm khác
{$unwind: { path : "$<field path/ array path>", <optional arguments>}}0Kết quả
Trong phần tiếp theo, mảng “màu sắc” được sử dụng để thực hiện thao tác $unwind. Chúng tôi cũng sử dụng các phương pháp sắp xếp và nhóm MongoDB để lấy giá trung bình theo màu xe
{$unwind: { path : "$<field path/ array path>", <optional arguments>}}1Kết quả
Hãy đơn giản hóa công thức trên trong một số bước để hiểu rõ hơn về quy trình. Bạn có thể xem cú pháp được định dạng hoàn chỉnh bên dưới
{$unwind: { path : "$<field path/ array path>", <optional arguments>}}2Bước 1
Ở bước đầu tiên, các tài liệu trong bộ sưu tập “vehiclesalesmain” được mở ra bằng cách sử dụng trường mảng “màu sắc”. Sau đó,serveNullAndEmptyArrays được đặt thành true để nắm bắt bất kỳ mảng bị thiếu, null hoặc trống nào trong kết quả đầu ra
{$unwind: { path : "$<field path/ array path>", <optional arguments>}}3Kết quả
Bước 2
Trong bước thứ hai, các tài liệu do thao tác $unwind tạo ra được nhóm theo phương pháp nhóm MongoDB bằng cách sử dụng màu và giá trung bình cho mỗi màu được tính
Cú pháp nhóm
{$unwind: { path : "$<field path/ array path>", <optional arguments>}}4Hoàn thành cú pháp
{$unwind: { path : "$<field path/ array path>", <optional arguments>}}5Kết quả
Bước 3
Cuối cùng, tập dữ liệu được nhóm được sắp xếp theo thứ tự giảm dần bằng phương pháp sắp xếp MongoDB
Cú pháp sắp xếp
{$unwind: { path : "$<field path/ array path>", <optional arguments>}}6Hoàn thành cú pháp
{$unwind: { path : "$<field path/ array path>", <optional arguments>}}1Kết quả
Sử dụng $unwind trên mảng nhúng
Khi bạn thực hiện thao tác $unwind trên một mảng được nhúng, thao tác này sẽ hoạt động giống như trên trường mảng thông thường. Thao tác $unwind sẽ giải cấu trúc các mục trong mỗi mảng được nhúng
Sử dụng bộ sưu tập “vehicleitems”, chúng ta sẽ chứng minh cách hoạt động của toán tử $unwind trên một mảng nhúng. Cùng xem qua bộ sưu tập “vật dụng xe cộ”
{$unwind: { path : "$<field path/ array path>", <optional arguments>}}8Kết quả
Trong phần tiếp theo, thao tác $unwind được thực hiện trên các tài liệu trên bằng cách sử dụng mảng nhúng “items”
{$unwind: { path : "$<field path/ array path>", <optional arguments>}}9Kết quả
Như bạn có thể thấy từ các tài liệu đầu ra, mỗi mục trong tất cả các mảng nhúng “mục” được giải cấu trúc thành các mục riêng lẻ. Bạn có thể giải cấu trúc thêm tập dữ liệu kết quả bằng cách sử dụng mảng "loại", chúng tôi sẽ thực hiện trong ví dụ tiếp theo