Я пытаюсь обновить массив поддокументов в MongoDB. Я знаю, что множественные обновления в одном запросе не поддерживаются оператором позиционирования $
.Позитанные обновления в MongoDB
Образец документа:
{
"_id": ObjectId("559a6c281816ba598cdf96cd"),
"collections": [
{
"id": 12,
"name": "a"
},
{
"id": 12,
"name": "b"
}
]
}
мне нужно обновить id : 12
поддокументы с дополнительным полем "price" : 12
. Я попробовал следующий запрос, но тот же поддокумент, который соответствует, обновляется, поэтому я добавил дополнительное условие "price" : {$exists : false}
, а также попытался "price" : {$ne : 12}
. Когда я добавляю "price" : {$exists : false}
, документ не возвращается. Я использую PyMongo и python. Поэтому мне нужно выполнить обновления в коде python и обновить документ. Есть ли обходной путь для этого?
Пробовал запрос:
db.scratch.update({ "collections.id" : 12 } , {"$set" : {"collections.$.price" : 12 }})
Пробовали с выше комбинации price : false
, price: {$exists : false}
, но они также не работают. Но я продолжаю возвращать сообщение о том, что один документ обновляется. Я использую mongo-hacker в своей оболочке mongo.
Я создаю средство миграции, в котором вся информация о клиенте присутствует как один документ.
{
"_id": ObjectId("559a2d9bfffe043444c72889"),
"age": NumberLong("23"),
"customer_address": [
{
"type": "Work",
"verified": true,
"address": "1A NY"
}
],
"customer_id": NumberLong("3"),
"customer_orders": [
{
"order_date": ISODate("2015-01-01T00:12:01Z"),
"order_id": NumberLong("2"),
"product_id": NumberLong("234")
},
{
"order_date": ISODate("2015-12-01T00:00:00Z"),
"order_id": NumberLong("3"),
"product_id": NumberLong("245")
},
{
"order_date": ISODate("2015-12-21T00:00:00Z"),
"order_id": NumberLong("4"),
"product_id": NumberLong("267")
},
{
"order_id": NumberLong("5"),
"order_date": ISODate("2015-12-29T00:00:00Z"),
"product_id": NumberLong("289")
},
{
"order_id": NumberLong("9"),
"order_date": ISODate("2015-02-01T00:12:05Z"),
"product_id": NumberLong("234")
}
]
}
Я получаю основную информацию из таблицы клиентов адрес из адресной таблицы клиентов и журнал продукта из другой таблицы, связанной по ссылке внешнего ключа в MySQL. Теперь я хочу обновить идентификатор продукта с правильным именем и ценой, чтобы я мог получить представление о клиенте, а не делать запрос, чтобы получить соответствующую цену для идентификатора продукта, а также, поскольку соединение отсутствует в
{
"_id": ObjectId("559a2d9bfffe043444c72889"),
"age": NumberLong("23"),
"customer_address": [
{
"type": "Work",
"verified": true,
"address": "1A NY"
}
],
"customer_id": NumberLong("3"),
"customer_orders": [
{
"name": "Brush",
"order_date": ISODate("2015-01-01T00:12:01Z"),
"order_id": NumberLong("2"),
"product_id": NumberLong("234"),
"price": 12
},
{
"order_date": ISODate("2015-12-01T00:00:00Z"),
"order_id": NumberLong("3"),
"product_id": NumberLong("245")
},
{
"order_date": ISODate("2015-12-21T00:00:00Z"),
"order_id": NumberLong("4"),
"product_id": NumberLong("267")
},
{
"order_id": NumberLong("5"),
"order_date": ISODate("2015-12-29T00:00:00Z"),
"product_id": NumberLong("289")
},
{
"name": "Brush",
"order_id": NumberLong("9"),
"order_date": ISODate("2015-02-01T00:12:05Z"),
"product_id": NumberLong("234"),
"price": 12
}
]
}
Пробовал запросы:
db.customer.update({"customer_orders.product_id" : 234 , "customer_orders.name" : {$exists : false}}, {"$set" : {"customer_orders.$.name" : "Brush", "customer_orders.$.price" : 12} })
возвращает 0 документы обновляются.
db.customer.update({"customer_orders.product_id" : 234 , "customer_orders.name" : {$exists : true}}, {"$set" : {"customer_orders.$.name" : "Brush", "customer_orders.$.price" : 12} })
возвращает 1 обновленный документ, но даже после последовательного выполнения одной и той же команды обновляется только первое поле. Итак, есть ли обходной путь или мне нужно сделать свое обновление в Python-клиенте?
Разве вы не начали свой вопрос с * «Я знаю, что множественные обновления в одном запросе не поддерживаются оператором позиционирования» *? Так как оба поддокумента имеют одинаковое значение «id», то что еще вы ожидаете? Не предполагайте, что вы использовали '" collections.price ": {" $ exists ": false}', поскольку это путь к элементу. –
@BlakesSeven Я думал, что возможны повторные обновления с одним и тем же условием, т. Е. Несколько обновлений в нескольких запросах. Когда у меня есть много документов того же идентификатора, где я хочу обновить. Я уточню вопрос с точным сценарием. – xtreak
Пожалуйста, сделайте так: «$ exists: false» не может соответствовать элементу. И если все элементы имеют одинаковый «id», тогда он будет только соответствовать первому. Различные значения «id» - это, конечно, другой случай. –