Pertama-tama 'Kamus di Kelas Pengguna' bukanlah ide yang baik. mengapa? Menambahkan objek tingkat ekstra memerlukan mendorong item baru ke larik, yang menyiratkan item lama akan dihapus, dan penyisipan ini disebut "memindahkan dokumen ". Memindahkan dokumen lambat dan MongoDB tidak begitu hebat dalam menggunakan kembali ruang kosong, sehingga banyak memindahkan dokumen dapat menghasilkan petak besar file data kosong (beberapa teks dalam buku 'MongoDB The Definitive Guide').
Lalu apa solusi yang tepat:anggap Anda memiliki koleksi bernama Blogs, dan ingin menerapkan solusi peringkat untuk posting blog Anda, dan juga melacak setiap operasi tarif berbasis pengguna.
Skema untuk dokumen blog akan seperti:
{
_id : ....,
title: ....,
....
rateCount : 0,
rateValue : 0,
rateAverage: 0
}
Anda memerlukan koleksi lain (Tarif) dengan skema dokumen ini:
{
_id: ....,
userId: ....,
postId:....,
value: ..., //1 to 5
date:....
}
Dan Anda perlu menentukan indeks yang tepat untuk itu:
db.Rates.ensureIndex({userId : 1, postId : 1})// very useful. it will result in a much faster search operation in case you want to check if a user has rated the post previously
Ketika pengguna ingin memberi peringkat, pertama-tama Anda perlu memeriksa apakah pengguna telah memberi peringkat pada posting atau tidak. asumsikan pengguna adalah 'user1'
, kuerinya adalah
var ratedBefore = db.Rates.find({userId : 'user1', postId : 'post1'}).count()
Dan berdasarkan ratedBefore
, jika !ratedBefore
kemudian masukkan dokumen tarif baru ke koleksi Tarif dan perbarui status blog, jika tidak, pengguna tidak diizinkan untuk memberi peringkat
if(!ratedBefore)
{
var postId = 'post1'; // this id sould be passed before by client driver
var userId = 'user1'; // this id sould be passed before by client driver
var rateValue = 1; // to 5
var rate =
{
userId: userId,
postId: postId,
value: rateValue,
date:new Date()
};
db.Rates.insert(rate);
db.Blog.update({"_id" : postId}, {$inc : {'rateCount' : 1, 'rateValue' : rateValue}});
}
Lalu apa yang akan terjadi pada rateAverage
?Saya sangat menyarankan untuk menghitungnya berdasarkan rateCount
dan rateValue
di sisi klien, mudah untuk memperbarui rateAverage
dengan mongoquery
, tetapi Anda tidak harus melakukannya. mengapa? Jawaban sederhananya adalah:ini adalah pekerjaan yang sangat mudah bagi klien untuk menangani pekerjaan semacam ini dan menempatkan rata-rata pada setiap dokumen blog memerlukan operasi pembaruan yang tidak perlu.
kueri rata-rata akan dihitung sebagai:
var blog = db.Blog.findOne({"_id" : "post1"});
var avg = blog.rateValue / blog.rateCount;
print(avg);
Dengan pendekatan ini, Anda akan mendapatkan kinerja maksimum dengan mongodb dan Anda dapat melacak setiap tarif berdasarkan pengguna, pos, dan tanggal.