Cấu trúc dữ liệu ở đây không được triển khai tốt, có rất nhiều vấn đề với cách cấu trúc này và nó hoàn toàn không phù hợp để tổng hợp. Các vấn đề chính ở đây là:
-
Cấu trúc của bạn không thực sự sử dụng bất kỳ mảng nào, ngay bây giờ nó không
-
Tất cả các tên khóa cụ thể đều là một vấn đề thực sự và điều này có thể tránh được.
Vì vậy, cách duy nhất để duyệt qua loại cấu trúc này là sử dụng JavaScript với mapReduce.
Xác định người lập bản đồ:
var mapper = function () {
for ( var n in this.versions ) {
for ( var k in this.versions[n].content ) {
if (
( k != 'confirmed' ) ||
( k != 'visited' ) )
emit(
{
type: this.chairtype,
key: k
},
this.versions[n].content[k]
);
}
}
};
Vì vậy, những gì điều này đang làm là chuyển đổi qua từng mục nhập phiên bản và sau đó là qua mọi thứ về nội dung. Khóa được phát ra cho từng khóa nội dung bạn muốn cũng như bởi phím "kiểu ghế". Và giá trị là giá trị phù hợp đó.
Và sau đó là một bộ giảm tốc:
var reducer = function (key,values) {
return ( Array.sum( values ) != 0 )
? Array.sum( values ) / values.length : 0;
};
Đây chỉ là một cách đơn giản để tạo ra giá trị trung bình từ tất cả các giá trị đến cho trình ánh xạ với cùng một khóa.
Vì vậy, mặc dù điều đó có thể hoạt động tốt, nhưng điều bạn nên làm là thay đổi cấu trúc của mình. Vì vậy, trên thực tế, nếu bạn có một cái gì đó như thế này:
{
"_id": ObjectId("52b85dfa32b6249513f15897"),
"parent": "47de3176-bbc3-44e0-8063-8920ac56fdc8",
"type": "chair",
"chairtype": "E",
"content": [
{ "key": "atkswlntfd", "value": 0, "version": 0 },
{ "key": "auwbsjqzir", "value": 0, "version": 0 },
{ "key": "avqrnjzbgd", "value": 0, "version": 0 }
]
}
Hoặc nói chung ít nhiều ở dạng đó, hoạt động tổng hợp trở nên rất đơn giản:
db.collection.aggregate([
{ "$unwind": "$content" },
{ "$group": {
"_id": {
"chairtype": "$chairtype",
"key": "$content.key"
},
"average": { "$avg": "$content.value" }
}}
])
Hoặc bất kỳ biến thể nào khác của điều này là bắt buộc, nhưng bây giờ nó có thể thực hiện được bằng cách thay đổi cấu trúc.
Vì vậy, nếu không có tài liệu được cấu trúc khác nhau, bạn sẽ cần sử dụng mapReduce để thực hiện việc này.