Bạn không thể chỉ trả lại tài liệu (hoặc tập hợp con) bằng cách sử dụng phân biệt. Theo tài liệu nó chỉ trả về mảng giá trị riêng biệt dựa trên khóa đã cho. Nhưng bạn có thể đạt được điều này bằng cách sử dụng thu nhỏ bản đồ
var _map = function () {
emit(this.hash.call_id, {doc:this});
}
var _reduce = function (key, values) {
var ret = {doc:[]};
var doc = {};
values.forEach(function (value) {
if (!doc[value.doc.hash.call_id]) {
ret.doc.push(value.doc);
doc[value.doc.hash.call_id] = true; //make the doc seen, so it will be picked only once
}
});
return ret;
}
Đoạn mã trên là tự giải thích, trên hàm bản đồ, tôi đang nhóm nó bằng khóa hash.call_id
và trả về toàn bộ tài liệu để nó có thể được xử lý bằng cách giảm hàm.
Trên chức năng giảm, chỉ cần lặp qua tập kết quả được nhóm và chỉ chọn một mục từ tập hợp được nhóm (trong số nhiều giá trị khóa trùng lặp - mô phỏng riêng biệt).
Cuối cùng tạo một số dữ liệu thử nghiệm
> db.disTest.insert({hash:{call_id:"1234"},something:"AAA"})
> db.disTest.insert({hash:{call_id:"1234"},something:"BBB"})
> db.disTest.insert({hash:{call_id:"1234"},something:"CCC"})
> db.disTest.insert({hash:{call_id:"5555"},something:"DDD"})
> db.disTest.insert({hash:{call_id:"5555"},something:"EEE"})
> db.disTest.find()
{ "_id" : ObjectId("4f30a27c4d203c27d8f4c584"), "hash" : { "call_id" : "1234" }, "something" : "AAA" }
{ "_id" : ObjectId("4f30a2844d203c27d8f4c585"), "hash" : { "call_id" : "1234" }, "something" : "BBB" }
{ "_id" : ObjectId("4f30a2894d203c27d8f4c586"), "hash" : { "call_id" : "1234" }, "something" : "CCC" }
{ "_id" : ObjectId("4f30a2944d203c27d8f4c587"), "hash" : { "call_id" : "5555" }, "something" : "DDD" }
{ "_id" : ObjectId("4f30a2994d203c27d8f4c588"), "hash" : { "call_id" : "5555" }, "something" : "EEE" }
và chạy bản đồ này giảm
> db.disTest.mapReduce(_map,_reduce, {out: { inline : 1}})
{
"results" : [
{
"_id" : "1234",
"value" : {
"doc" : [
{
"_id" : ObjectId("4f30a27c4d203c27d8f4c584"),
"hash" : {
"call_id" : "1234"
},
"something" : "AAA"
}
]
}
},
{
"_id" : "5555",
"value" : {
"doc" : [
{
"_id" : ObjectId("4f30a2944d203c27d8f4c587"),
"hash" : {
"call_id" : "5555"
},
"something" : "DDD"
}
]
}
}
],
"timeMillis" : 2,
"counts" : {
"input" : 5,
"emit" : 5,
"reduce" : 2,
"output" : 2
},
"ok" : 1,
}
Bạn nhận được tài liệu đầu tiên của tập hợp riêng biệt. Bạn có thể làm tương tự trong mongoid bằng cách đầu tiên xâu chuỗi các hàm map / Reduce và gọi mapreduce như thế này
MyObject.collection.mapreduce(_map,_reduce,{:out => {:inline => 1},:raw=>true })
Hy vọng nó sẽ hữu ích