Переименовать поле во встроенном документе с помощью PyMongo - PullRequest
0 голосов
/ 27 сентября 2018

У меня есть коллекция в mongodb, и я хочу переименовать некоторые поля в названия.Моя коллекция выглядит так:

    {
    "_id": "",
    "user": "5a02d87ac12d314721bd9a15",
    "item": {
        "5b20db50a32c0e02693ffad6": {
            "item_value": [{
                "timepstamp": "",
                "value": 0.2
            }, {
                "timepstamp": "",
                "value": 0.8
            }, {
                "timepstamp": "",
                "value": 0.9
            }]
        },
        "843ujsafu88gfs88987898f": {
            "item_value": [{
                "timepstamp": "",
                "value": 0.2
            }, {
                "timepstamp": "",
                "value": 0.8
            }, {
                "timepstamp": "",
                "value": 0.9
            }]
        }
    }
}

Я хочу переименовать "5b20db50a32c0e02693ffad6" и "843ujsafu88gfs88987898f", которые являются ключами после элемента с новыми значениями, скажем, "12345x" и "12345y"

Как я могу выполнить этот запрос в пимонго?Я могу получить значение из коллекции с помощью следующего кода:

db = client['db']
collection = db['col']
res = collection.find({})

for item in res:
    items= item["item"]
    for key in items:
         print (key)
    ## collection.update({}, {$rename: {item["item"][key]: item["item"][new_item_id]}}, False, True)

Этот код возвращает ключи, которые я хочу переименовать.Как я могу это сделать?

РЕДАКТИРОВАТЬ: Я пытался использовать обновление коллекции и метод переименования.Кажется, это не работает.Как я могу изменить только это поле и как я буду правильно использовать пимонго здесь?

EDIT2: В моем случае мне нужно сделать что-то подобное:

 _id = res['_id']
 item.pop('_id')   # this is imp
 _user = item['user']
 item.pop('user')   # this is imp

 collection.update({'_id': _id, 'user': _user }, {$set: item})

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Чтобы переименовать поле в MongoDB, мы обычно используем операцию обновления $rename, которая прекрасно работает и со внедренным документом .

from pymongo import MongoClient


uri = mongodb://127.0.0.1:27017"

old_fields_names = ["5b20db50a32c0e02693ffad6",
                    "843ujsafu88gfs88987898f"]
new_fields_names = ["12345x", "12345y"]
with MongoClient(uri) as client:
    db = client.db
    col = db.col
    update_doc = {f"item.{old}": f"item.{new}"
                  for old, new in zip(old_fields_names, new_field_names)}
    update = {"$rename": update_doc}
    col.update_many({}, update)

Обратите внимание наиспользование диспетчера контекста aka с оператором для открытия соединения с базой данных, которое гарантирует, что соединение будет закрыто, когда мы закончим с операцией, чтобы избежать утечки ресурсов.

0 голосов
/ 27 сентября 2018

Я думаю, что вы уже достигли верных шагов, осталось всего несколько шагов.Ниже будет работать.Кроме того, я предполагаю, что у вас уже есть сопоставление, какой ключ вы хотите заменить, а какой -

db = client['db']
collection = db['col']
res = collection.find({})

for doc in res:
    items= doc["item"]
    for key in items:
         # Now suppose you want to replace this key 
        if key want to replace:
             temp = copy.deepcopy(items[key])
             items["new_Key_name"] = temp
             items.pop(key)  # deleting old key with data

     # Now one document has been modified with expected key Now update the DB
     _id = copy.deepcopy(doc['_id'])
     doc.pop('_id')   # this is imp
     collection.update({'_id': _id }, {$set: doc})

Теперь одно предложение в конце.Не используйте вышеуказанный подход, потому что внутри Loop есть запросы к БД, что не очень хорошо.Узнайте о BulkWrite, приведенном в документации Pymongo.Это очень просто.

...