Điều kiện truy vấn với .distinct ()
áp dụng cho "lựa chọn tài liệu" chứ không phải các mục nhập mảng chứa "trong" tài liệu. Nếu bạn cần "lọc" nội dung mảng thì bạn áp dụng .aggregate ()
thay vào đó, cũng như xử lý một chút bài đăng để chỉ nhận "giá trị" trong phản hồi mảng.
db.collection.aggregate([
{ "$match": { "_id": "TEST" } },
{ "$unwind": "$payload" },
{ "$match": { "payload.status": { "$in": ["TRUE","FALSE"] } } },
{ "$group": { "_id": "$payload._id" } },
]).map( d => d._id );
Các phần chính ở đó là $ unwind
giai đoạn đường ống mà bạn thực hiện chủ yếu vì bạn muốn các giá trị từ bên trong mảng sau này sử dụng làm khóa cho $ nhóm
trên. Về cơ bản, điều này tạo ra một tài liệu mới cho mỗi thành viên mảng, nhưng mỗi tài liệu chỉ chứa thành viên mảng đó. Nó "không chuẩn hóa" cho cấu trúc MongoDB có chứa mảng.
Điều tiếp theo là $ so khớp
sau
đường ống, hoạt động giống như bất kỳ truy vấn nào và chỉ chọn các tài liệu phù hợp với các điều kiện. Vì tất cả các thành viên của mảng bây giờ là "tài liệu" nên các mục nhập không khớp (dưới dạng tài liệu) sẽ bị loại trừ. Bạn có thể luân phiên sử dụng $ filter
để giải nén trong khi vẫn là một mảng, nhưng vì chúng tôi cần $ unwind
cho giai đoạn tiếp theo, chúng tôi cũng có thể chỉ cần $ match
.
Tại thời điểm này, bạn chỉ còn lại với các mục nhập mảng phù hợp với các điều kiện. $ group
là để có được các giá trị "khác biệt", vì vậy, thông thường bạn sẽ thực hiện việc này trên phạm vi lựa chọn rộng hơn chỉ là một tài liệu đơn lẻ hoặc bất kỳ thứ gì mà các giá trị ở đây chưa khác biệt. Vì vậy, đây thực sự chỉ là giữ tất cả các hành vi giống nhau của .distinction ()
còn nguyên vẹn.
Cuối cùng, vì đầu ra của .aggregate ()
khác với thiết kế của .distinct ()
trong đó nó trả về "tài liệu" trong kết quả, chúng tôi chỉ cần sử dụng mã <> .map ()
để xử lý kết quả con trỏ và chỉ trả về "giá trị" từ thuộc tính tài liệu cụ thể dưới dạng "mảng".