簡體   English   中英

MongoDB:在數組中插入和更新

[英]MongoDB : Insert and Update in an array

我有“ _id”和“ ProductLot”。 如果存在ProductLot,如何將批次數組中的數量“ 0”更新為“ 1”;如果不存在,則如何追加新的批次元素?

"_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));               

請有人幫我解決這個問題嗎?

在這種情況下,使用$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's 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條件匹配某項,使我們的$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 ] ]
);

在這里,我使用$位置更新運算符訪問條件中匹配的特定數組元素。 這使我們可以編寫$inc而不用擔心匹配元素的索引。

同樣,我們可以在此處檢查$result['n'] 如果仍然為0,則可以假定沒有文檔與_id相匹配(完全獨立的錯誤)。 但是,如果此時n為1,我們就成功地增加了數量,我們的工作就完成了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM