【发布时间】:2014-07-29 04:09:01
【问题描述】:
首先:我使用的是 Mongo 2.6 和 Mongoose 3.8.8
我有以下架构:
var Link = new Schema({
title: { type: String, trim: true },
owner: { id: { type: Schema.ObjectId }, name: { type: String } },
url: { type: String, default: '', trim: true},
stars: { users: [ { name: { type: String }, _id: {type: Schema.ObjectId} }] },
createdAt: { type: Date, default: Date.now }
});
我的收藏已经有 50 万份文档。
我需要的是使用自定义策略对文档进行排序。我最初的解决方案是使用聚合框架。
var today = new Date();
//fx = (TodayDay * TodayYear) - ( DocumentCreatedDay * DocumentCreatedYear)
var relevance = { $subtract: [
{ $multiply: [ { $dayOfYear: today }, { $year: today } ] },
{ $multiply: [ { $dayOfYear: '$createdAt' }, { $year: '$createdAt' } ] }
]}
var projection = {
_id: 1,
url: 1,
title: 1,
createdAt: 1,
thumbnail: 1,
stars: { $size: '$stars.users'}
ranking: { $multiply: [ relevance, { $size: '$stars.users' } ] }
}
var sort = {
$sort: { ranking: 1, stars: 1 }
}
var page = 1;
var limit = { $limit: 40 }
var skip = { $skip: ( 40 * (page - 1) ) }
var project = { $project: projection }
Link.aggregate([project, sort, limit, skip]).exec(resultCallback);
在 100k 之前它工作得很好,之后查询变得越来越慢。
我怎么能做到这一点?
重新设计?
投影的错误使用我在做什么?
感谢您的宝贵时间!
【问题讨论】:
-
您是否考虑过将计算得出的
ranking字段添加到您的架构和文档中,然后对其进行索引,而不是每次都即时计算? -
@JohnnyHK 感谢您抽出宝贵时间。我希望我可以预先计算排名,但我不能。排名字段取决于动态计算的星数。我说清楚了吗,我的意思是,你明白我的意思吗?
-
这个想法是,每当您更新文档时,您还会重新计算其
ranking值并将其与文档的其余部分一起存储。
标签: javascript node.js mongodb mongoose aggregation-framework