Nếu có thể, tôi khuyên bạn nên đặt điều kiện trong khi lưu trữ dữ liệu để bạn có thể kiểm tra độ trung thực nhanh chóng (isInStudentsList
). Sẽ rất nhanh nếu thực hiện loại truy vấn đó.
Nếu không, có một cách tương đối phức tạp là sử dụng đường dẫn khung Tổng hợp để thực hiện những gì bạn muốn trong một truy vấn:
db.students.aggregate(
{$project:
{studentId: 1, studentIdComp: "$students.id"}},
{$unwind: "$studentIdComp"},
{$project : { studentId : 1,
isStudentEqual: { $eq : [ "$studentId", "$studentIdComp" ] }}},
{$match: {isStudentEqual: true}})
Với ví dụ đầu vào của bạn, đầu ra sẽ là:
{
"result" : [
{
"_id" : ObjectId("517b88decd483543a8bdd95b"),
"studentId" : 23,
"isStudentEqual" : true
}
],
"ok" : 1
}
Giải thích ngắn gọn về các bước:
- Xây dựng bản chiếu của tài liệu chỉ với
studentId
và một trường mới với một mảng chỉ chứaid
(vì vậy tài liệu đầu tiên nó sẽ chứa[23, 55]
. - Sử dụng cấu trúc đó, $ thư giãn
. Điều đó tạo ra một tài liệu tạm thời mới cho mỗi phần tử mảng trong
studentIdComp
mảng. - Bây giờ, lấy các tài liệu đó và tạo một chiếu tài liệu mới, tiếp tục có
studentId
và thêm một trường mới có tên làisStudentEqual
so sánh sự bằng nhau của hai trường,studentId
vàstudentIdComp
. Hãy nhớ rằng tại thời điểm này, có một tài liệu tạm thời duy nhất chứa hai trường đó. - Cuối cùng, hãy kiểm tra xem giá trị so sánh
isStudentEqual
là true và trả lại các tài liệu đó (sẽ chứa tài liệu gốc_id
vàstudentId
. - Nếu sinh viên có trong danh sách nhiều lần, bạn có thể cần nhóm các kết quả trên
studentId
hoặc_id
để tránh trùng lặp (nhưng tôi không biết rằng bạn cần điều đó).