2013-08-23 3 views
3

У меня есть тысячи документов в этом формате:MongoDB: Удаление поля из ВСЕХ поддокументов в поле массива

{ 
"_id" : ObjectId("51e98d196b01c2085c72d731"), 
"messages" : [ 
    { 
     "_id" : ObjectId("520167056b01c20bb9eee987"), 
     "id" : ObjectId("520167056b01c20bb9eee987"), 

    }, 
    { 
     "_id" : ObjectId("520167056b01c20bb9eee988"), 
     "id" : ObjectId("520167056b01c20bb9eee988"), 

    }, 
    { 
     "_id" : ObjectId("520167056b01c20bb9eee989"), 
     "id" : ObjectId("520167056b01c20bb9eee989"), 
    } 
], 
} 

Мне нужно удалить поле дубликата «ID». Это то, что я пробовал:

db.forum_threads.update({}, {$unset: {"messages.$.id": 1}}, {multi: true}); 

Это ошибка я получаю:

Cannot apply the positional operator without a corresponding query field containing an array. 

ответ

10

Причина вы получаете эту ошибку, потому что вы не имеете никакого предиката в предложении фильтра , Вы можете сделать это:

mongos> db.test.update({"messages.id": {$exists: true}}, {$unset: {"messages.$.id":true}}, {multi:true}) 

И вы не получите сообщение об ошибке - на самом деле один из документов будет иметь атрибут id удален. Проблема в том, что оператор позиционирования соответствует только элементу FIRST массива, который соответствует вашему предикату, он не соответствует всем элементам. Большая проблема заключается в том, что в настоящее время невозможно обновить все элементы массива в MongoDB (https://jira.mongodb.org/browse/SERVER-1243).

Вам потребуется либо выполнить итерацию по каждому элементу массива с помощью численной позиции («messages.0.id», «messages.1.id» и т. Д.), Либо вы можете вывести массив в ваше приложение , прокрутите элементы и обновите их, а затем сохраните массив.

Вы можете видеть из билета JIRA, что этот вопрос был открыт довольно долго, но 10gen, похоже, не считает его очень важным.

+0

У меня было предчувствие, что это невозможно. Думаю, мне нужно пойти по альтернативному маршруту, спасибо! – user1236803

+0

Спасибо за объяснение, мне не хватало ". $." в статье $ unset. Неожиданным поведением является то, что он удаляет только атрибут из первого поддока, который он встречает, но это все еще помогает в ущемлении, я просто запускал его несколько раз, пока не удалил их все. – SteveO7

Смежные вопросы