13

我在 MongoDB 中有一个名为 CrawlUser 的集合。它有一个名为 CrawlStatus 的列表,它是 CrawlStatus 对象的列表。CrawlStatus 有一个名为 LastErrorMessage 的属性,我想从集合中删除它。

我尝试执行以下操作来删除它,但它没有工作...没有给出错误消息,但 LastErrorMessage 列仍然存在。

db.CrawlUser.update( {}, { $unset: { "CrawlStatuses.LastErrorMessage": 1 } }, false, true);

任何想法我做错了什么?

另一个相关问题,如果我对一个非常大的集合(数百万行)中的列执行 $unset 命令,mongodb 会用完服务器上的所有 ram(好像它试图将整个集合存储在内存中),然后服务器崩溃。当您有大量集合时,是否有更好的方法来删除列?

4

2 回答 2

13

使用空参数的更新似乎不起作用。我在 mongo shell 和 mongoconsole 中尝试过。在 mongoconsole 中,它给出了一个关于更新期望第一个参数是数组或对象的错误。

但是,您可以使用 $exists 查找查询来执行相同的操作。

尝试:

`db.CrawlUser.update( {CrawlStatuses:{$exists:true}}, { $unset: { "CrawlStatuses.LastErrorMessage": 1 } }, false, true);`

这对我有用。

请记住,根据文档, $exists 不使用索引,因此它会更慢。我建议添加一个参数,您可以在其上添加索引并在执行 $unset 时对其进行查询。

于 2011-02-14T07:46:28.543 回答
0

看起来你在这里有几个问题。

#1:$unset命令

据我所知,这应该可以正常工作。我在测试中得到以下输出:

MongoDB shell version: 1.6.5
connecting to: test
> db.foo.save( { _id : 1, status : { err : 'blah', y : 1 } } )
> db.foo.save( { _id : 2, status : { err : 'blahblah', y : 5 } } )
> db.foo.find()
{ "_id" : 1, "status" : { "err" : "blah", "y" : 1 } }
{ "_id" : 2, "status" : { "err" : "blahblah", "y" : 5 } }
> db.foo.update( { }, { $unset : { "status.err" : 1 } }, false, true )
> db.foo.find()
{ "_id" : 1, "status" : { "y" : 1 } }
{ "_id" : 2, "status" : { "y" : 5 } }

#2:用尽内存

如果我对非常大的集合中的列执行 $unset 命令,mongodb 会用完服务器上的所有 ram(就好像它试图将整个集合存储在内存中一样)

这正是 MongoDB 想要做的。MongoDB 使用内存映射文件。MongoDB 会将所有数据拉入 RAM 并让操作系统管理虚拟内存问题。

因此,当您执行没有索引的查询时,您基本上是在要求 MongoDB 遍历集合中的每个项目。它基本上是一个对所有数据进行操作的巨大 for 循环,因此这将需要从磁盘加载所有内容。

到目前为止,这一切都很正常。

...然后服务器崩溃

这不正常。我已经在数亿个文档上运行了这种类型的更新命令,而不会导致服务器崩溃。您能否提供有关此问题的更多详细信息?你有日志文件吗?

如果是这样,我建议将您的错误带到 Google 网上论坛,以便他们帮助确定崩溃的根源。 http://groups.google.com/group/mongodb-user

于 2011-02-15T03:44:18.457 回答