Mặc dù bạn dường như đã tiếp cận cấu trúc này do sự cố với các bản cập nhật trong việc sử dụng các mảng lồng nhau, nhưng bạn thực sự chỉ gây ra một vấn đề khác bằng cách làm một việc khác không thực sự được hỗ trợ và đó là không có "ký tự đại diện" khái niệm để tìm kiếm các khóa không xác định bằng cách sử dụng các toán tử truy vấn chuẩn là tối ưu.
Cách duy nhất bạn có thể thực sự tìm kiếm những dữ liệu đó là sử dụng mã JavaScript trên máy chủ để duyệt qua các khóa bằng cách sử dụng $where
. Đây rõ ràng không phải là một ý tưởng thực sự tốt vì nó đòi hỏi bạo lực đánh giá thay vì sử dụng những thứ hữu ích như chỉ mục, nhưng nó có thể được tiếp cận như sau:
db.theses.find(function() {
var relations = this.relations;
return Object.keys(relations).some(function(rel) {
return relations[rel].type == "interpretation";
});
))
Trong khi điều này sẽ trả về những đối tượng từ bộ sưu tập có chứa giá trị lồng nhau bắt buộc, nó phải kiểm tra từng đối tượng trong bộ sưu tập để thực hiện đánh giá. Đây là lý do tại sao đánh giá như vậy thực sự chỉ nên được sử dụng khi được ghép nối với thứ gì đó có thể sử dụng trực tiếp chỉ mục thay thế dưới dạng giá trị cứng từ đối tượng trong bộ sưu tập.
Vẫn còn giải pháp tốt hơn là xem xét việc tu sửa dữ liệu để tận dụng các chỉ mục trong tìm kiếm. Trường hợp cần thiết phải cập nhật thông tin "xếp hạng", thì về cơ bản, "san bằng" cấu trúc coi mỗi phần tử "xếp hạng" là dữ liệu mảng duy nhất để thay thế:
{
"_id": "aeokejXMwGKvWzF5L",
"text": "test",
"relationsRatings": [
{
"relationId": "cF6iKAkDJg5eQGsgb",
"type": "interpretation",
"originId": "uFEjssN2RgcrgiTjh",
"ratingId": 1,
"ratingScore": 5
},
{
"relationId": "cF6iKAkDJg5eQGsgb",
"type": "interpretation",
"originId": "uFEjssN2RgcrgiTjh",
"ratingId": 2,
"ratingScore": 6
}
]
}
Tất nhiên, việc tìm kiếm bây giờ khá đơn giản:
db.theses.find({ "relationsRatings.type": "interpretation" })
Và tất nhiên, vị trí $
toán tử bây giờ có thể được sử dụng với cấu trúc phẳng hơn:
db.theses.update(
{ "relationsRatings.ratingId": 1 },
{ "$set": { "relationsRatings.$.ratingScore": 7 } }
)
Tất nhiên điều này có nghĩa là dữ liệu "có liên quan" trùng lặp cho mỗi giá trị "xếp hạng", nhưng nói chung đây là chi phí để cập nhật theo vị trí phù hợp vì đây là tất cả những gì được hỗ trợ với một cấp độ lồng ghép mảng duy nhất.
Vì vậy, bạn có thể buộc logic phải phù hợp với cách bạn đã cấu trúc nó, nhưng làm như vậy không phải là một ý tưởng hay và sẽ dẫn đến các vấn đề về hiệu suất. Tuy nhiên, nếu nhu cầu chính của bạn ở đây là cập nhật thông tin "xếp hạng" thay vì chỉ thêm vào danh sách bên trong, thì cấu trúc phẳng hơn sẽ có lợi hơn và tất nhiên là tìm kiếm nhanh hơn rất nhiều.