如何删除子文档但将内容保留在mongodb中

时间:2019-01-14 01:21:58

标签: json mongodb mongodb-query

我运行了一个脚本,该脚本用大约60k个文档填充了我的收藏集。由于类型错误,它在所有文档中创建了子文档,并且包含重复信息。我确实不需要/想要子文档,但是我不想完全删除它,因为我希望保留其中的一个字段。

这是我的文档结构

{
    "_id" : ObjectId(""),
    "title" : "",
    "url" : "",
    "description" : "", 
    "author" : "",
    "publishedAt" : "",
    "content" : "" 
    "source" : {
        "id" : "Source",
        "name" : "Source"
    },
    "urlToImage" : ""
}

如果可能的话,我最终要做的是删除源子文档,但保留名称字段。下面是我想要的。

{
    "_id" : ObjectId(""),
    "title" : "",
    "url" : "",
    "description" : "", 
    "author" : "",
    "publishedAt" : "",
    "content" : "" 
    "name" : "Source"
    "urlToImage" : ""
}

我知道这将是一个多部分查询。我只是不想犯错误并删除整个子文档,而无需先拉出字段。

1 个答案:

答案 0 :(得分:0)

选项1-$重命名和$ unset

  1. 使用$rename运算符将source.name重命名为name

    • 也许通过一些检查(过滤器),您不会用name覆盖现有的null
  2. 然后使用$unset运算符删除source子文档

    • 再次确保,您可以添加过滤器以确保要取消设置name的文档中已经存在source字段

选项2-查找和$ set + $ unset

  1. 获取文档

  2. 使用$ set和$ unset更新文档

示例(在Python中):

while True:
    doc = db.find_one({
         '_id': 'foobar',
         'source.name': {'$exists': True},
    })
    res = db.update_one(
        {
            '_id': 'foobar',
            'source.name': doc['source']['name'],
        }, {
            '$set': {'name': doc['source']['name']},
            '$unset': {'source': ''},
        }
    )
    if res.modified_count == 1:
        break
    # if nothing was modified then somebody has updated
    # the source.name right after our find_one()