MongoDB: вставка и обновление в массиве

0

У меня есть "_id" и "ProductLot". Как я могу обновить Qty "0" до "1" в массиве Lot, если ProductLot присутствует или добавляет новый элемент Lot, если он отсутствует?

"_id" : ObjectId("5462e44c599e5c6c1300000a"),
"LocationName" : "Putaway", 
"Owner" : "", 
"Status" : "1", 
"Scrap" : "0", 
"Lot" : [{      
     "Qty" :"6",   
     "ProductLot" : ObjectId("5462dbd9599e5c200e000000"), 
     "Product" : ObjectId("543ca7be4cf59d400c000004"),       
     "Movement" :[ {"OriginId" : "266",Qty:2,Type:"DN"},
           {"OriginId" : "267" , Qty:1 , Type:"DN"},
           {"OriginId" : "2" , Qty:3 , Type:"IM"},

        ]
    },  
    {      
     "Qty" :"0",   
     "ProductLot" : ObjectId("5462dbd9599e5c200e000003"),  
     "Product" : ObjectId("543ca7be4cf59d400c000004"),    
     "Movement" :[ {"OriginId" : "266",Qty:2,Type:"DN"},
           {"OriginId" : "267" , Qty:1 , Type:"DN"},
           {"OriginId" : "2" , Qty:-3 , Type:"IM"},
        ]

    }] 
}

EG: У меня есть "ProductLot": ObjectId ("5462dbd9599e5c200e000000"), присутствующий в массиве, поэтому он должен обновлять число от 0 до 1; однако "ProductLot": ObjectId ("5462dbd9599e5c200e00000a") недоступен в массиве, поэтому должен добавить новый элемент в массив.

PHP-код, который не обновляет создание массива добавления каждый раз:

            $inventoryId = new \MongoId($_POST["inventoryid"]);
            $productLotId = new \MongoId($invlotid);
            $originId = $_POST['id'];
            //$lotcontent = [ /* whatever this looks like */ ];

            $lotcontent = array(
                     'Qty' => $invqty,
                     'ProductLot' => new \MongoId($invlotid),
                     'Product'=>$invproduct,
                     'Movement'=> array(
                            array(
                            'OriginId' => $_POST['id'],
                            'Qty' => $invqty,
                            'Type'=> 'DN',              
                            ),  )                   
                     );
            $invcolname = 'Inventory';
            $result = $mongo->$dbname->$invcolname->update(
            // Match an inventory without the specific ProductLot/OriginId element
            array(
                '_id' => $inventoryId,
                'Lot' =>    array(
                    '$not' =>   array(
                        '$elemMatch' => array(
                            'ProductLot' => $productLotId,
                            //'OriginId' => $originId,
                        ),
                    ),
                ),
            ),
            // Append a new element to the Lot array field
            array('$push' => array( 'Lot' => $lotcontent ))
            );

            $movementcontent =  array(
                            'OriginId' => $_POST['id'],
                            'Qty' => $invqty,
                            'Type'=> 'DN',              
                            );

            $result = $mongo->$dbname->$invcolname->update(
            // Match an inventory without the specific ProductLot/OriginId element
            array(
                '_id' => $inventoryId,
                'Lot' =>    array(
                    //'$not' =>     array(
                        '$elemMatch' => array(
                            'ProductLot' => $productLotId,                              
                            'Movement'=>array(
                                '$not' =>   array(
                                    '$elemMatch' => array(
                                        'OriginId' => $originId,
                                    )
                                )
                            )                               
                        ),
                   // ),
                ),
            ),
            // Append a new element to the Lot.Movement array field
            array('$push' => array( 'Lot.$.Movement' => $movementcontent ))
            );


            $result = $mongo->$dbname->$invcolname->update(
                // Match an inventory with a specific ProductLot/OriginId element
              array(
                    '_id' => $inventoryId,
                    'Lot' => array(
                        '$elemMatch' => array(
                            'ProductLot' => $productLotId,
                            //'OriginId' => $originId,
                            'Movement'=>array(
                                '$elemMatch' => array(
                                        'OriginId' => $originId,
                                    )
                            )
                        ),
                    ),
                ),
                // Update the "Qty" field of the first array element matched (if any)                  
               //array( '$set' => array( 'Lot.$.Qty' => 'Updated' )),
               array( '$set' => array( 'Lot.$.Movement.$.Qty' => $invqty )),
            array('upsert' => true));               

Пожалуйста, помогите мне решить это?

Теги:

1 ответ

1

Использование $addToSet в этом случае проблематично, потому что следующие элементы lot считаются разными:

{
    "Qty" :0,
    "ProductLot" : ObjectId("5462dbd9599e5c200e000003"),
    "Product" : ObjectId("543ca7be4cf59d400c000004"),
    "OriginId" : "266"
}

{
    "Qty" :5,
    "ProductLot" : ObjectId("5462dbd9599e5c200e000003"),
    "Product" : ObjectId("543ca7be4cf59d400c000004"),
    "OriginId" : "266"
}

Первым элементом, вероятно, будет то, что вы добавляете (с количеством 0 или 1), а второй элемент будет одним и тем же логическим элементом партии, просто с увеличенной величиной. Если последний элемент уже существовал в массиве, я полагаю, вы хотели бы, чтобы ваше приложение увеличивало количество от 5 до 6 вместо добавления первого элемента, который по существу является дубликатом.

Мы определенно нуждаемся в двух обновлениях здесь, но я бы предложил следующее:

// Let assume the following identifiers...
$inventoryId = new MongoId($_POST['inventoryid']);
$productLotId = new MongoId($invlotid);
$originId = new MongoId($_POST['id']);
$lotcontent = [ /* whatever this looks like */ ];

$result = $collection->update(
    // Match an inventory without the specific ProductLot/OriginId element
    [
        '_id' => $inventoryId,
        'Lot' => [
            '$not' => [
                '$elemMatch' => [
                    'ProductLot' => $productLotId,
                    'OriginId' => $originId,
                ],
            ],
        ],
    ],
    // Append a new element to the Lot array field
    [ '$push' => [ 'Lot' => $lotcontent ] ]
);

MongoCollection::update() вернет результирующий документ с полем n указывающим количество затронутых документов. Поскольку мы не используем multiple параметр и также сопоставляем не более одного документа с помощью _id, мы можем ожидать, что n будет либо 0, либо 1. Если n равно 0, мы либо не смогли найти документ инвентаризации с этим _id либо мы нашел его, но у него уже был элемент Lot с идентификаторами продукта и происхождения (т.е. наши критерии $elemMatch соответствовали чему-то, аннулируя наше отрицание). Если n равно 1, это значит, что мы нашли документ инвентаризации, он не содержал соответствующий элемент Lot, и мы добавили его (т.е. наша работа выполнена).

Предполагая, что n равно 0, мы должны выпустить еще одно обновление и попытаться увеличить количество:

$result = $collection->update(
    // Match an inventory with a specific ProductLot/OriginId element
    [
        '_id' => $inventoryId,
        'Lot' => [
            '$elemMatch' => [
                'ProductLot' => $productLotId,
                'OriginId' => $originId,
            ],
        ],
    ],
    // Update the "Qty" field of the first array element matched (if any)
    [ '$inc' => [ 'Lot.$.Qty' => 1 ] ]
);

Здесь я использую оператор $ positional update для доступа к определенному элементу массива, который был сопоставлен в критериях. Это позволяет нам создавать $inc не беспокоясь об индексе совпадающего элемента.

Опять же, мы можем проверить $result['n'] здесь. Если он еще 0, то можно предположить, что ни один документ не соответствует нашему _id (полностью отдельная ошибка). Но если n равно 1 в этой точке, мы успешно увеличиваем количество и выполняем нашу работу.

  • 0
    использование '$ inc' - получение ошибки: 'MongoCursorException' с сообщением ': невозможно увеличить с помощью нечислового аргумента: {Lot. $. Qty: "4"}'
  • 0
    Я пытаюсь обновить ошибку получения вложенного массива: db.Inventory.update ({"_ id": ObjectId ("5462e44c599e5c6c13000000"), "Lot.ProductLot": ObjectId ("54648649599e5c1c06000003"), "Lot.Moved. "rigin". 267 "}, {" Лот $ Движение $ Кол-во ":".... 9" });
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню