想象一下包含100个对象的MongoDB文档。我们希望将数组长度固定保持在100
。当一批新对象到达时(可能是1,5,10等),我们希望用新对象更新数组,同时删除等量的旧对象,这样数组长度将保持不变。我选择将MongoDB中的数组读入我的应用程序,进行一些修改,然后使用$set
更新数组:
var newData = [
{ ... },
{ ... },
{ ... },
{ ... },
{ ... }
];
var oldData = Collection.findOne({exchange: 'The Exchange', market: 'The Market'}).data;
newData = newData.concat(oldData).slice(0, 100);
Collection.update(
{
exchange: 'The Exchange',
market: 'The Market'
},
{
$set: {
data: newData
}
}
MongoDB中是否有可能$push
将新内容放到前面,同时使用$pop
从后面移除相同数量的对象?
答案 0 :(得分:5)
是否可以在MongoDB中将$推到前面,同时使用$ pop从后面删除相同数量的对象?
是的,使用$slice
:
$push: {
data: {
$each: [ { ... }, { ... } ], // your batch
$slice: -100 // maximum array size
}
}
有关示例,请参阅http://docs.mongodb.org/manual/tutorial/limit-number-of-elements-in-updated-array/
答案 1 :(得分:4)
答案是"是"和"不"把它放在一个令人困惑的条款中。在单一更新中,您不能对同一数组执行$push
和$pull
操作。对于相同的路径"不允许这样做。操作,因为$push
或$pull
实际上并未确定在当前更新语法中以任何顺序发生。
然而,在您的具体情况下,这不是您所要求的。为了做你想做的事,MongoDB支持$slice
修饰符,它可以与$each
一起使用。这将有效地限制"添加新项目时数组的总大小。
按照你的例子:
Collection.update(
{ "exchange": "The Exchange", "market": "The Market" },
{ "$push": { "data": { "$each": newData, "$slice": 100 } } }
)
这有效地将数组的大小限制为第一个100
成员,同时向其添加新项目。
请注意,在" minimongo"的客户端版本中可能不支持此功能。由流星实施。你可以做的是在服务器上执行它,并通过发布公开方法。有很多例子可以向您展示如何使用发布。