如何在mongoose中进行查询,以查找用户是否有50个文档,然后删除最旧的文档并添加新文档,如果不只是添加新文档?
这是我的尝试:
Notifications.findOne({_id: userId}, function(err, results) {
if(err) throw err;
if(results.length < 50) {
saveNotification();
} else {
Notifications.findByIdAndUpdate(userId, {pull: //WHAT GOES HERE),
function(err, newNotify) {
if(error) throw error;
saveNotification();
});
}
});
function saveNotification() {
var new_notification = new Notification ({
notifyToUserId: creatorId,
notifyFromUserId: null,
notifyMsg: newmsg,
dateNotified: dateLastPosted
});
new_notification.save(function(err, results){
if(!err) {
console.log('notification has been added to the db');
cb(null, resultObject);
} else {
console.log("Error creating notification " + err);
}
});
}
正如@Pio所提到的,我不认为您可以在当前模式的一个查询中完成它。但是,如果您有机会更改模式,则可以使用固定大小的数组模式,该模式将在以下文章
中描述<更新后数组中的元素数量限制>基本上你可以把用户的通知保存在一个文档中。文档的Key将是userId,通知将存储在一个数组中。那么下面的查询将实现您的目标。
Notifications.update(
{ _id: userId },
{
$push: {
notifications: {
$each: [ notificationObject ], // insert your new notification
$sort: { dateNotified: 1 }, // sort by insertion date
$slice: -50 // retrieve the last 50 notifications.
}
}
}
)
更新后数组中的元素数量限制>我不确定你能在一个查询中做到这一点,但你可以.count({user: yourUser'})
,然后根据计数.insert(newDocument)
或更新最旧的,这样你就不会删除+插入。
封顶集合按您的意愿行事。如果您定义大小为50的capped collection,它将只保留50个文档,并且当您插入更多文档时将覆盖旧数据。检查
- http://mongoosejs.com/docs/guide.html封顶
- http://docs.mongodb.org/manual/core/capped-collections/
new Schema({..}, { capped: { size: 50, max: 50, autoIndexId: true } });
请记住,当使用capped collection时,您只能进行就地更新。更新整个文档可能会改变集合的大小,从而删除其他文档。
I ended up using cubbuk's answer and expanding it to add a notification if there is no array to start with along with upsert...
Notification.findOneAndUpdate({notifyToUserId: to}, {
$push: {
notifyArray: {$each: [newNotificationObject], // insert your new notification
$sort: { dateNotified: 1 }, // sort by insertion date
$slice: -50 // retrieve the last 50 notifications.
}
}
}, {upsert: true}, function(err, resultOfFound) {
if(err) throw err;
if(resultOfFound == null) {
var new_notification = new Notification ({
notifyToUserId: to,
notifyArray: [newNotificationObject]
});
new_notification.save(function(err, results){
if(!err) {
console.log('notification has been added to the db');
cb(null, resultObject);
} else {
console.log("Error creating notification " + err);
}
});
} else {
cb(null, resultObject);
}
});