gpt4 book ai didi

arrays - 从文档数组中删除最旧的 N 个元素

转载 作者:行者123 更新时间:2023-12-02 15:11:01 25 4
gpt4 key购买 nike

我的 mongodb 中有一个文档,其中包含一个非常大的数组(大约 10k 项)。我试图只保留数组中最新的 1k(因此删除前 9k 元素)。该文档看起来像这样:

    {
"_id" : 'fakeid64',
"Dropper" : [
{
"md5" : "fakemd5-1"
},
{
"md5" : "fakemd5-2"
},
...,
{
"md5": "fakemd5-10000"
}
]
}

我该如何实现?

最佳答案

这里正确的操作实际上涉及$push。运算符(operator)使用 $each$slice修饰符。使用 $push 最初可能会违反直觉从数组中“删除”项目,但当您看到预期的操作时,实际用例就很清楚了。

db.collection.update(
{ "_id": "fakeid64" },
{ "$push": { "Dropper": { "$each": [], "$slice": -1000 } }
)

事实上,您可以像这样运行整个集合:

db.collection.update(
{ },
{ "$push": { "Dropper": { "$each": [], "$slice": -1000 } },
{ "multi": true }
)

这里发生的是 $each 的修饰符将一组项目“添加”到 $push 中操作,在这种情况下我们留空,因为我们实际上不想添加任何东西。 $slice给定“负”值的修饰符实际上是说在执行更新时保留数组中存在的“最后 n 个”元素,这正是您要问的。

一般的“预期”情况是使用 $slice添加新元素以将数组“维持”在“最大”给定长度时,在本例中为 1000。因此,您通常会串联使用实际“添加”新项目,如下所示:

db.collection.update(
{ "_id": "fakeid64" },
{ "$push": { "Dropper": { "$each": [{ "md5": "fakemd5-newEntry"}], "$slice": -1000 } }
)

这将追加 $each 中提供的新项目,同时还会从数组的“开始”中删除任何项目,其中给定添加的总长度大于 1000。


其他地方错误地说明您将使用 $pullAll提供的数组内容列表已存在于文档中,但该操作实际上是对数据库的两次请求。

误解是请求作为“一个”发送,但实际上不是,并且基本上被解释为更长的形式(正确使用 .slice() ):

var md5s = db.collection.findOne({ "_id": "fakeid64" }).Dropper.slice(-1000);

db.collection.update(
{ "_id": "fakeid64" },
{ "$pullAll": { "Dropper": md5s } }
)

因此您可以看到,当您认为文档中数组的状态“可能”可能在数组内容和更新时的实际“写入”操作,因为它们是分开发生的。

这就是 MongoDB 为 $push 提供原子运算符的原因与 $slice正如所证明的那样。因为它不仅效率更高,而且还考虑了实际修改发生时被修改文档的实际“状态”。

关于arrays - 从文档数组中删除最旧的 N 个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43811070/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com