Работа непосредственно со встроенными документами в Mongodb - PullRequest
0 голосов
/ 08 декабря 2011

Я работаю со сложным mongodoc, в котором есть несколько встроенных документов, представляющих предметы в инвентаре. Весь документ можно рассматривать как полный инвентарь. Ключ «разделы» содержит еще один ключ «элементы», который содержит отдельные элементы и их данные, такие как цена, описание и т. Д. Каждый элемент также имеет GUID, поэтому его можно искать по отдельности.

Я написал хранимую функцию для поиска отдельных предметов по идентификатору, которая выглядит следующим образом:

function (item_id) {
    var pls = db.pricelists.findOne({'sections.items.item_id':item_id});
    if (!pls) {
        return null;
    }
    for (var sect in pls.sections) {
        for (var item in pls.sections[sect].items) {
            if (pls.sections[sect].items[item].item_id == item_id) {
                return pls.sections[sect].items[item];
            }
        }
    }
}

Пока все работает, найди. Проблема в том, что я хочу изменить этот встроенный документ и сохранить его обратно в родительском документе. Примеры, приведенные в оболочке:

var item = db.eval('find_item(1)');
item.users_who_bought = [11,16];
item;

Это выводит обратно на консоль правильный пункт.

{
    "name" : "item00",
    "order" : 0,
    "item_id" : 1,
    "hidden" : false,
    "variants" : [
        {
            "price" : "0.56",
            "label" : "variant000"
        },
        {
            "price" : "1.56",
            "label" : "variant001"
        },
        {
            "price" : "2.56",
            "label" : "variant002"
        }
    ],
    "desc" : "Sociis habitasse, integer pellentesque sit! Nisi purus tincidunt amet mus scelerisque amet, pid enim eros phasellus dolor sociis nunc dictumst sed nunc, integer hac!",
        "users_who_bought" : [11,16]

}

Я в недоумении по поводу того, как сформулировать запрос для обновления этого документа встроенного элемента обратно в его родительский документ. Я пробовал что-то вроде этого (например, item_id здесь жестко закодирован как один):

db.pricelists.update({'sections.item.item_id': 1}, {$set: {'sections.item.item_id[1]': item}})

Но это не работает правильно и пытается добавить к массиву элементов.

Существует ли способ оптовой передачи измененного встроенного документа в оператор обновления, подобный этому, выборочно по значению в документе? Или я думаю об этом неправильно, и мне нужно написать еще одну сохраненную функцию итератора, которая снова найдет элемент, а затем обновит весь родительский документ новыми глубоко внедренными значениями? Спасибо!

Ответы [ 2 ]

1 голос
/ 09 декабря 2011

Если вы хотите изменить элемент внутри массива, я предлагаю сначала использовать условный $ pull, а затем обновленный элемент $ push.

В вашем случае это будет немного сложнее, поскольку у вас есть массив разделов. Таким образом, вам может понадобиться использовать оператор $, а затем массив $ pull / $ push для элементов.

0 голосов
/ 08 декабря 2011

Если я правильно вас понимаю, ваша цель - получить доступ и изменить значение в массиве в определенной позиции. Если это так, вы можете немного изменить свой запрос:

db.pricelists.update(
  {'sections.item.item_id': 1}, 
  {$set: {'sections.item.item_id.$': item}}
)

Другими словами, вам не нужно использовать [1], $ относится к первому совпадению, указанному в первом параметре метода .update (). Для более подробной информации смотрите позиционные операторы: http://www.mongodb.org/display/DOCS/Updating#Updating-The%24positionaloperator

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...