Bạn có thể làm điều đó với khung tổng hợp như một thao tác "hai bước". Đầu tiên là tích lũy các mục vào một mảng thông qua $push
withing a $group
và sau đó sử dụng $concat
với $reduce
trên mảng được tạo trong phép chiếu cuối cùng:
db.collection.aggregate([
{ "$group": {
"_id": "$tag_id",
"client_id": { "$push": "$client_id" }
}},
{ "$addFields": {
"client_id": {
"$reduce": {
"input": "$client_id",
"initialValue": "",
"in": {
"$cond": {
"if": { "$eq": [ "$$value", "" ] },
"then": "$$this",
"else": {
"$concat": ["$$value", ",", "$$this"]
}
}
}
}
}
}}
])
Chúng tôi cũng áp dụng $cond
ở đây để tránh nối một chuỗi trống với dấu phẩy trong kết quả, vì vậy nó trông giống một danh sách được phân tách hơn.
FYI Có sự cố với JIRA SERVER-29339
yêu cầu $reduce
được triển khai dưới dạng biểu thức tích lũy
để cho phép nó sử dụng trực tiếp trong một $group
giai đoạn đường ống. Không có khả năng xảy ra sớm, nhưng về mặt lý thuyết, nó sẽ thay thế $push
ở trên và làm cho hoạt động trở thành một giai đoạn đường ống duy nhất. Cú pháp đề xuất mẫu về vấn đề JIRA.
Nếu bạn không có $reduce
(yêu cầu MongoDB 3.4) sau đó chỉ cần đăng quá trình con trỏ:
db.collection.aggregate([
{ "$group": {
"_id": "$tag_id",
"client_id": { "$push": "$client_id" }
}},
]).map( doc =>
Object.assign(
doc,
{ "client_id": doc.client_id.join(",") }
)
)
Sau đó, dẫn đến cách thay thế khác là thực hiện việc này bằng cách sử dụng mapReduce
nếu bạn thực sự phải:
db.collection.mapReduce(
function() {
emit(this.tag_id,this.client_id);
},
function(key,values) {
return [].concat.apply([],values.map(v => v.split(","))).join(",");
},
{ "out": { "inline": 1 } }
)
Tất nhiên, kết quả đầu ra trong mapReduce
cụ thể dạng _id
và giá trị value
như một tập hợp các khóa, nhưng về cơ bản nó là đầu ra.
Chúng tôi sử dụng [].concat.apply([],values.map(...))
bởi vì đầu ra của "bộ giảm" có thể là "chuỗi được phân tách" vì mapReduce
hoạt động tăng dần với kết quả lớn và do đó đầu ra của bộ giảm tốc có thể trở thành "đầu vào" trên một đường chuyền khác. Vì vậy, chúng ta cần mong đợi rằng điều này có thể xảy ra và xử lý nó cho phù hợp.