MongoDB: nasıl..bir tane birden fazla koleksiyon verileri Birleştirmek?
Nasıl (MongoDB) bir koleksiyon içinde birden çok koleksiyon verileri birleştirebilir miyim?
Öyleyse nasıl eğer harita-azaltın kullanabilir miyim?
Bir acemi olduğum gibi büyük ölçüde bazı örnek seviniriz.
CEVAP
Ancak bunu yapamazsın, gerçek zamanlı, çalışma göster-azaltmak için birden çok kez birleştirme verileri birlikte kullanarak "azaltmak" seçeneği MongoDB 1.8 göster/azaltmak (http://www.mongodb.org/display/DOCS/MapReduce#MapReduce-Outputoptions). Bir _ıd olarak kullanabileceğiniz her iki koleksiyon bazı önemli olması gerekir.
Örneğin, diyelim ki users
toplama ve comments
bir koleksiyonu var ve her yorum için bazı kullanıcı demografik bilgileri içeren yeni bir koleksiyon var.
Hadi users
toplama aşağıdaki alanları vardır ki:
- _ıd
- ad
- soyad
- ülke
- cinsiyet
- yaÅŸ
Ve sonra comments
toplama aşağıdaki alanlar vardır:
- _ıd
- kullanıcı kimliği
- yorum
- yarattı
Bu haritayı küçült/.
var mapUsers, mapComments, reduce;
db.users_comments.remove();
// setup sample data - wouldn't actually use this in production
db.users.remove();
db.comments.remove();
db.users.save({firstName:"Rich",lastName:"S",gender:"M",country:"CA",age:"18"});
db.users.save({firstName:"Rob",lastName:"M",gender:"M",country:"US",age:"25"});
db.users.save({firstName:"Sarah",lastName:"T",gender:"F",country:"US",age:"13"});
var users = db.users.find();
db.comments.save({userId: users[0]._id, "comment": "Hey, what's up?", created: new ISODate()});
db.comments.save({userId: users[1]._id, "comment": "Not much", created: new ISODate()});
db.comments.save({userId: users[0]._id, "comment": "Cool", created: new ISODate()});
// end sample data setup
mapUsers = function() {
var values = {
country: this.country,
gender: this.gender,
age: this.age
};
emit(this._id, values);
};
mapComments = function() {
var values = {
commentId: this._id,
comment: this.comment,
created: this.created
};
emit(this.userId, values);
};
reduce = function(k, values) {
var result = {}, commentFields = {
"commentId": '',
"comment": '',
"created": ''
};
values.forEach(function(value) {
var field;
if ("comment" in value) {
if (!("comments" in result)) {
result.comments = [];
}
result.comments.push(value);
} else if ("comments" in value) {
if (!("comments" in result)) {
result.comments = [];
}
result.comments.push.apply(result.comments, value.comments);
}
for (field in value) {
if (value.hasOwnProperty(field) && !(field in commentFields)) {
result[field] = value[field];
}
}
});
return result;
};
db.users.mapReduce(mapUsers, reduce, {"out": {"reduce": "users_comments"}});
db.comments.mapReduce(mapComments, reduce, {"out": {"reduce": "users_comments"}});
db.users_comments.find().pretty(); // see the resulting collection
Bu noktada, birleştirilmiş verileri içeren yeni bir koleksiyon users_comments
denilen olacak ve artık kullanabilirsiniz. Bu azaltılmış koleksiyonları var _id
hangi anahtar olduğunu yayan olarak harita işlevleri ve daha sonra bütün değerler alt-nesne içinde value
anahtar değerleri değil üst düzeyinde olan bu düşük belgeler.
Bu biraz basit bir örnektir. Daha koleksiyonları ile bu azaltılmış koleksiyonu kadar bina tutmak için istediğiniz kadar tekrar edebilirsiniz. Ayrıca bu süreçte veri özetleri ve toplamalardan yapabilirsin. Muhtemel ve mevcut alanları toplayarak korumak için mantığı daha karmaşık hale geldikçe, birden fazla işlevi azaltmak tanımlarsınız.
Şimdi de Bir dizide bu kullanıcının tüm yorumları ile her kullanıcı için bir belge olduğunu unutmayın. Eğer bir bire-bir ilişki bire-bir değil çok veri birleştirme olsaydık, düz olacak ve sadece böyle bir fonksiyonu azaltmak kullanabilirsiniz:
reduce = function(k, values) {
var result = {};
values.forEach(function(value) {
var field;
for (field in value) {
if (value.hasOwnProperty(field)) {
result[field] = value[field];
}
}
});
return result;
};
Eğer yorum başına bir belge yani users_comments
toplama düzleştirmek istiyorsanız, Ayrıca bu çalışma:
var map, reduce;
map = function() {
var debug = function(value) {
var field;
for (field in value) {
print(field ": " value[field]);
}
};
debug(this);
var that = this;
if ("comments" in this.value) {
this.value.comments.forEach(function(value) {
emit(value.commentId, {
userId: that._id,
country: that.value.country,
age: that.value.age,
comment: value.comment,
created: value.created,
});
});
}
};
reduce = function(k, values) {
var result = {};
values.forEach(function(value) {
var field;
for (field in value) {
if (value.hasOwnProperty(field)) {
result[field] = value[field];
}
}
});
return result;
};
db.users_comments.mapReduce(map, reduce, {"out": "comments_with_demographics"});
Bu teknik kesinlikle anında yapılmamalıdır. Bir cron veya birleştirilmiş verileri düzenli aralıklarla güncelleyen böyle bir şey için uygun değil. Sen muhtemelen kaçmak istiyor ensureIndex
yeni koleksiyonu için emin olun sorguları gerçekleştirmek karşılaştırdın hızlı (unutmayın, verileriniz hala içinde bir value
anahtar, Yani eğer düşünüyorsanız Endeksi comments_with_demographics
yorum created
zaman olur db.comments_with_demographics.ensureIndex({"value.created": 1});
Nasıl bir SQL sorgu, birden fazla tabl...
nasıl mongodb birden fazla dizi öğeler...
Nasıl alt için birden fazla koşul veri...
Nasıl birden fazla sınıflar ile bir öğ...
Nasıl böyle büyük mükafat içinde birde...