Как удалить вложенный документ, но сохранить содержимое в mongodb - PullRequest
0 голосов
/ 14 января 2019

Я запустил скрипт, который заполнил мою коллекцию примерно 60 тысячами документов. Из-за опечатки он создал вложенные документы во всех документах и ​​содержит дублирующую информацию. Мне действительно не нужен / не нужен вложенный документ, но я не хочу полностью его удалять, потому что хочу, чтобы поле в нем оставалось.

Это моя структура документа

{
    "_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 голосов
/ 14 января 2019

вариант 1 - $ переименовать и $ unset

  1. используйте $ rename оператор для переименования source.name в name

    • возможно, с некоторой проверкой (фильтром), что вы не собираетесь перезаписывать существующие name с помощью null
  2. затем удалите вложенный документ source, используя $ unset operator

    • снова, просто чтобы убедиться, что вы можете добавить фильтр, чтобы убедиться, что поле 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...