這是我現在的代碼:
router.get('/questions/best', function(req,res,next){
Question.find({}).exec(function(err,results){
if (err){return next(err)}
let top15 = [];
for(let i = 0; i< results.length; i ){
let dislikestouse = results[i].dislikes[0]
let ratio = 0
if(dislikestouse > 0){
ratio = results[i].likes[0]/dislikestouse
}
else{
ratio = results[i].likes[0]/1
}
}
res.render('content', { whichOne: 5, user: req.user, questions: top15 });
})
});
results 是資料庫中的每個問題,top15 應該只是顯示的問題,因為它們具有最高的比率并呈現到模板中。我嘗試使用 if 陳述句來防止它除以 0,因為它會導致錯誤。
如何通過查找每個結果是否大于 top15 中的任何專案然后將其放置在正確的位置來對每個結果進行排序?我使用純 JavaScript。訪問結果的不喜歡和喜歡的數量搜索第一個專案,因為它存盤長度,就像典型的喜歡陣列是:[2,'username1', 'username2']. 這是一個問題的方案:
const Question = mongoose.model(
"Question",
new Schema({
title: { type: String, required: true },
text: { type: String },
authorUsername: { type: String, required: true },
dateCreated: {},
answers: { type: Array, required: true },
likes: { type: Array, required: true },
dislikes: { type: Array, required: true },
tag: { type: String, required: true },
views: {type: Array, required:true},
})
);
這是一個問題的例子:
_id:620935985f6865b4e85c333d
title:"How do i make a lemon?"
text:"yeet"
authorUsername:"SweetWhite"
dateCreated:2022-02-13T16:45:12.598 00:00
answers:
Array
likes:
Array
0:1
1:"SweetWhite"
dislikes:
Array
0:0
tag:
"Social"
views:
Array
0:1
1:"SweetWhite"
__v:0
謝謝!
uj5u.com熱心網友回復:
您可以使用陣列方法:
排序:https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
切片:https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
地圖:https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
這是我為您的問題嘗試的片段:
function sortQuestions(results) {
const questionsWithRatio = results.map((result) => ({
...result,
ratio: result.likes[0] / Math.max(result.dislikes[0], 1),
}));
// console.log(questionsWithRatio);
const top15 = questionsWithRatio
.sort((a, b) => b.ratio - a.ratio)
.slice(0, 15);
console.log(top15);
}
uj5u.com熱心網友回復:
上面的答案是一個極好的純 Javascript 解決方案。然而,我們可能不想從資料庫中拖出 1000 個或更多的專案,只是為了在客戶端排序和挑選 15 個。給定一組這樣的檔案:
var r = [
{likes: ['A','A'], dislikes: ['A','A']},
{likes: ['A','A']},
{dislikes: ['A','A']},
{likes: ['A','A','A','A','A'], dislikes: ['A','A']},
{likes: ['A','A','A','A','A','A','A','A','A'], dislikes: ['A','A']},
{likes: ['A','A','A','A','A','A','A','A'], dislikes: ['A','A']},
{likes: ['A','A','A','A','A','A','A'], dislikes: ['A','A']},
{likes: ['A'], dislikes: ['A','A']}
];
然后這是一個聚合,它將排序和“切片”邏輯驅動到資料庫中:
db.foo.aggregate([
// Protect against missing fields with $ifNull
// Protect against division by zero dislikes using max[1,size]
{$addFields: {ratio: {$divide:[{$size:{$ifNull:["$likes",[]]}},
{$max:[1,{$size:{$ifNull:["$dislikes",[]]}}]}
]}
}},
{$sort: {ratio:-1}},
{$limit: 3} // change to 15 for the real dataset
]);
如果我們必須適應陣列的“運行長度編碼”性質,例如[2, 'user1', 'user2'],那么 agg 非常相似,僅使用$arrayElemAtto grab array[0] 而不是使用$size:
var r = [
{likes: [2, 'A','A'], dislikes: [2, 'A','A']},
{likes: [2, 'A','A']},
{dislikes: [2, 'A','A']},
{likes: [5, 'A','A','A','A','A'], dislikes: [2, 'A','A']},
{likes: [9, 'A','A','A','A','A','A','A','A','A'], dislikes: [2, 'A','A']},
{likes: [8, 'A','A','A','A','A','A','A','A'], dislikes: [2, 'A','A']},
{likes: [7, 'A','A','A','A','A','A','A'], dislikes: [2, 'A','A']},
{likes: [1, 'A'], dislikes: [2, 'A','A']}
];
db.foo.aggregate([
// Protect against missing fields with $ifNull but this time it is not
// an empty array [] but rather an array of one elem, the length, which
// is 0:
{$project: {ratio: {$divide:[
{$arrayElemAt:[{$ifNull:["$likes",[0]]}, 0]},
{$max:[1, {$arrayElemAt:[{$ifNull:["$dislikes",[0]]}, 0]}]}
]}
}},
{$sort: {ratio:-1}},
{$limit: 3}
]);
{ "_id" : 4, "ratio" : 4.5 }
{ "_id" : 5, "ratio" : 4 }
{ "_id" : 6, "ratio" : 3.5 }
uj5u.com熱心網友回復:
在我嘗試提供幫助之前,請嘗試提高代碼的可讀性。您可以查找async/await和ES6 語法來幫助您。
此外,如果您使用的是像 Visual Studio Code 這樣的 IDE,那么您可以安裝prettier,它會自動格式化您的代碼。
這是一個粗略的解決方案:
router.get('/questions/best', function(req,res,next){
Question.find({}).exec(function(err,results){
if (err) return next(err);
let top15 = [];
// note that the code is slightly more readable already
results.forEach(result => {
const dislikesToUse = result.dislikes[0]
let ratio = 0;
if(dislikesToUse > 0) {
ratio = result.likes[0]/dislikesToUse
} else {
ratio = result.likes[0]/1
}
// push each result with ratio to top15
top15.push({...result, ratio})
});
// sort top15 by ratio
top15.sort((a,b) => b.ratio - a.ratio) // do a.ratio - b.ratio to change order
// get only the top 15
top15 = top15.slice(0, 15)
res.render('content', { whichOne: 5, user: req.user, questions: top15 });
})
});
筆記
這只是一種方法,可能不是最有效的方法。您還應該考慮 Mongo 的聚合函式。
您還應該重新考慮您的架構設計。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/423998.html
標籤:javascript mongodb 表达 猫鼬 哈巴狗
