Node.js Mongoose切片不限制数组大小
我正在开发一个应用程序,但Mongoose在更新时限制了数组大小。我对MongoDB或Mongoose不太熟悉,但我希望这个项目能增加我的知识。我尝试了一些我在SOF上质疑的其他解决方案,但似乎都不适合我。这是我对这个问题的分析 库:猫鼬5.7.7 摘要:在日志文档中,我只希望保留最新的10个日志,旧的日志将从阵列中推出 问题:对于我的当前查询,切片似乎没有限制文档的数量。阵列只是在继续增长Node.js Mongoose切片不限制数组大小,node.js,mongodb,mongoose,mongoose-schema,Node.js,Mongodb,Mongoose,Mongoose Schema,我正在开发一个应用程序,但Mongoose在更新时限制了数组大小。我对MongoDB或Mongoose不太熟悉,但我希望这个项目能增加我的知识。我尝试了一些我在SOF上质疑的其他解决方案,但似乎都不适合我。这是我对这个问题的分析 库:猫鼬5.7.7 摘要:在日志文档中,我只希望保留最新的10个日志,旧的日志将从阵列中推出 问题:对于我的当前查询,切片似乎没有限制文档的数量。阵列只是在继续增长 ActivityLog.updateOne( { guild }, { $push: {
ActivityLog.updateOne(
{ guild },
{
$push: {
logs: {
$each: [{ ...log }]
},
$slice: -10
}
},
{ upsert: true }
);
在您的实现中,这实际上可能是一个更大的问题。以下是实际使用中的基本情况,以表明它确实有效:
const { Schema } = mongoose = require('mongoose');
const uri = 'mongodb://localhost:27017/test';
const options = { useNewUrlParser: true, useUnifiedTopology: true };
mongoose.set("debug", true);
mongoose.set("useFindAndModify", false);
mongoose.set("useCreateIndex", true);
const demoSchema = new Schema({
_id: Number,
fifo: [Number]
},{ _id: false });
const Demo = mongoose.model('Demo', demoSchema, 'demo');
const log = data => console.log(JSON.stringify(data, undefined, 2));
(async function() {
try {
const conn = await mongoose.connect(uri, options);
await Promise.all(
Object.values(conn.models).map(m => m.deleteMany())
);
let counter = 0;
await new Promise((resolve, reject) =>
setInterval(async () => {
try {
let result = await Demo.findByIdAndUpdate(
1,
{ "$push": { "fifo": { "$each": [counter], "$slice": -3 } } },
{ upsert: true, new: true }
);
log(result);
} catch(e) {
reject(e)
}
counter++;
}, 2000)
);
} catch (e) {
console.error(e);
} finally {
mongoose.disconnect();
}
})()
在几次迭代中(为了简洁起见,这里使用-3
),您将看到:
Mongoose: demo.deleteMany({}, {})
Mongoose: demo.findOneAndUpdate({ _id: 1 }, { '$setOnInsert': { __v: 0 }, '$push': { fifo: { '$each': [ 0 ], '$slice': -3 } }}, { upsert: true, remove: false, projection: {}, returnOriginal: false })
{
"fifo": [
0
],
"_id": 1,
"__v": 0
}
Mongoose: demo.findOneAndUpdate({ _id: 1 }, { '$setOnInsert': { __v: 0 }, '$push': { fifo: { '$each': [ 1 ], '$slice': -3 } }}, { upsert: true, remove: false, projection: {}, returnOriginal: false })
{
"fifo": [
0,
1
],
"_id": 1,
"__v": 0
}
Mongoose: demo.findOneAndUpdate({ _id: 1 }, { '$setOnInsert': { __v: 0 }, '$push': { fifo: { '$each': [ 2 ], '$slice': -3 } }}, { upsert: true, remove: false, projection: {}, returnOriginal: false })
{
"fifo": [
0,
1,
2
],
"_id": 1,
"__v": 0
}
Mongoose: demo.findOneAndUpdate({ _id: 1 }, { '$setOnInsert': { __v: 0 }, '$push': { fifo: { '$each': [ 3 ], '$slice': -3 } }}, { upsert: true, remove: false, projection: {}, returnOriginal: false })
{
"fifo": [
1,
2,
3
],
"_id": 1,
"__v": 0
}
Mongoose: demo.findOneAndUpdate({ _id: 1 }, { '$setOnInsert': { __v: 0 }, '$push': { fifo: { '$each': [ 4 ], '$slice': -3 } }}, { upsert: true, remove: false, projection: {}, returnOriginal: false })
{
"fifo": [
2,
3,
4
],
"_id": 1,
"__v": 0
}
Mongoose: demo.findOneAndUpdate({ _id: 1 }, { '$setOnInsert': { __v: 0 }, '$push': { fifo: { '$each': [ 5 ], '$slice': -3 } }}, { upsert: true, remove: false, projection: {}, returnOriginal: false })
{
"fifo": [
3,
4,
5
],
"_id": 1,
"__v": 0
}
Mongoose: demo.findOneAndUpdate({ _id: 1 }, { '$setOnInsert': { __v: 0 }, '$push': { fifo: { '$each': [ 6 ], '$slice': -3 } }}, { upsert: true, remove: false, projection: {}, returnOriginal: false })
{
"fifo": [
4,
5,
6
],
"_id": 1,
"__v": 0
}
因此,这确实保留了一个指定
$slice
长度的数组,并且从数组的末尾开始,由于负数的原因,这两种方法都将数组增大到设置的大小,然后删除除最后添加的成员以外的所有成员。我确实启动了一个小项目,以查看它是否正常工作。你提到过它可能是我实现它的方式,你对此有什么见解或细节吗?@Rykuno我相信“见解”就是你评论过的在你面前工作的代码的例子。这就是重点。正如答案所显示的那样,它是按设计工作的。我知道你的例子是有效的。但是对于我们的实现,我想知道问题是什么,为什么不进行切片:)。“在您的实现中,这实际上可能是一个更大的问题”。因为我用它来解决我的问题,所以我继续把它作为公认的答案发布。我的问题很简单。$slice应该与$each操作符位于同一对象内。我想事情就这么简单。