[英]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.