如何从子集合中删除列

时间:2011-02-13 22:18:59

标签: mongodb unset

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

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

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

任何想法我做错了什么?

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

2 个答案:

答案 0 :(得分:13)

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

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

尝试:

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

这对我有用。

请记住,基于文档,$ exists不使用索引,因此速度会慢一些。我建议添加一个可以添加索引的参数,并在执行$ unset时查询它。

答案 1 :(得分: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遍历集合中的每个项目。它基本上是一个巨大的循环操作所有数据,因此这需要从磁盘加载所有内容。

到目前为止,这都是正常的。

  

...然后服务器崩溃

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

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