gpt4 book ai didi

mongodb - 如何在 mongodb 中进行条件更新?

转载 作者:可可西里 更新时间:2023-11-01 10:39:24 25 4
gpt4 key购买 nike

我正在尝试像下面的代码行一样更新文档的子文档

$bulkbatch = new MongoDB\Driver\BulkWrite(['ordered' => true]);  

$subDocumentStatus = array(
"Status" => array(
"CurrentStatus" => $this->EmployeeStatus,
"StatusDate" => new MongoDB\BSON\UTCDateTime(strtotime($this->EmployeeStatusDate)*1000),
"IsActive" => $IsActive
)
);

$bulkbatch->update(
array(
'_id' => new MongoDB\BSON\ObjectID($this->id)
),
array(
'$addToSet' => $subDocumentStatus
),
[
'multi' => true,
'upsert' => false
]
);

$this->manager->executeBulkWrite($this->collection, $bulkbatch);

我有这样的文档

{
"EmployeeNumber": "123456",
"Instructor": NumberInt(1),
"Department": ObjectId("5a8173e6d2ccda13240015a4"),
"FirstName": "Faiza",
"MiddleName": "Yousuf",

"Status": [
{
"CurrentStatus": "Joined",
"StatusDate": ISODate("2018-02-28T23:00:00.0Z"),
"IsActive": NumberInt(1)
}
],
...
...
}

如果 $this->EmployeeStatus 包含“Joined”并且 $this->EmployeeStatusDate 包含一些不同的值,例如上面的文档,它包含“2019-05-28T23:00:00.0Z”(不同于之前的值),那么它应该被更新。

上面的代码是插入另一个子文档具有像

这样的值
  "Status": [
{
"CurrentStatus": "Joined",
"StatusDate": ISODate("2018-02-28T23:00:00.0Z"),
"IsActive": NumberInt(1)
},
{
"CurrentStatus": "Joined",
"StatusDate": ISODate("2019-05-28T23:00:00.0Z"),
"IsActive": NumberInt(1)
}
],
...

我希望在 Joined 的情况下应该更新现有的子文档。

请帮忙!!!

最佳答案

有两个 Mongo 调用的解决方案;首先尝试更新现有的子文档;如果没有修改子文档,则在主文档中插入一个。

这是一个证明解决方案有效的单元测试(主要功能是 updateOrInsert):

require_once __DIR__ . '/MongoTestHelper.php';

use MongoDB\BSON\ObjectID;
use MongoDB\BSON\UTCDateTime;
use tests\Dudulina\MongoTestHelper;

class TmpTest extends \PHPUnit_Framework_TestCase
{
/** @var \MongoDB\Collection */
private $collection;

/** @var ObjectID */
private $_id;

public function test_subdocumentExists()
{
$statusDate = new UTCDateTime(strtotime("2018-02-28T23:00:00.0Z"));
$employeeStatus = "Joined";

/**
* Test data
*/
$this->collection->insertOne([
"_id" => $this->_id,
"EmployeeNumber" => "123456",
"Instructor" => 1,
"Department" => new ObjectID("5a8173e6d2ccda13240015a4"),
"FirstName" => "Faiza",
"MiddleName" => "Yousuf",

"Status" => [
[
"CurrentStatus" => $employeeStatus,
"StatusDate" => $statusDate,
"IsActive" => 1,
],
],
]);

/**
* the real test
*/
$this->updateOrInsert($employeeStatus, $statusDate, 0);


/**
* we verify the execution
*/
$document = $this->collection->findOne([
"_id" => $this->_id,
]);

$this->assertCount(1, $document['Status']);
$this->assertSame(0, $document['Status'][0]['IsActive']);

}

public function test_subdocumentDoesNotExists()
{
$statusDate = new UTCDateTime(strtotime("2018-02-28T23:00:00.0Z"));
$employeeStatus = "Joined";

/**
* we insert some test data
*/
$this->collection->insertOne([
"_id" => $this->_id,
"EmployeeNumber" => "123456",
"Instructor" => 1,
"Department" => new ObjectID("5a8173e6d2ccda13240015a4"),
"FirstName" => "Faiza",
"MiddleName" => "Yousuf",

"Status" => [
[
"CurrentStatus" => 'SomeOtherStatus',
"StatusDate" => new UTCDateTime(strtotime("2010-02-28T23:00:00.0Z")),
"IsActive" => 1,
],
],
]);

/**
* the real test
*/
$this->updateOrInsert($employeeStatus, $statusDate, 0);

/**
* we verify the execution
*/
$document = $this->collection->findOne([
"_id" => $this->_id,
]);

/**
* now there are 2 subdocuments inserted
*/
$this->assertCount(2, $document['Status']);

/**
* we verify the second document
*/
$secondSubDocument = $document['Status'][1];

$this->assertSame(0, $secondSubDocument['IsActive']);
$this->assertSame('Joined', $secondSubDocument['CurrentStatus']);
$this->assertTrue($statusDate->toDateTime()->getTimestamp() === $secondSubDocument['StatusDate']->toDateTime()->getTimestamp());

}

/**
* The function that you should do
*/
private function updateOrInsert($employeeStatus, $statusDate, $isActive)
{
$updateResult = $this->collection->updateOne([
"_id" => $this->_id,
"Status.CurrentStatus" => $employeeStatus,
"StatusDate" => ['$ne' => $statusDate],
], [
'$set' => [
'Status.$.StatusDate' => $statusDate,
'Status.$.IsActive' => $isActive,
],
], [
'upsert' => false,
]);

if ($updateResult->getModifiedCount() === 0) {
$this->collection->updateOne([
"_id" => $this->_id,
], [
'$addToSet' => [
'Status' => [
"CurrentStatus" => $employeeStatus,
"StatusDate" => $statusDate,
"IsActive" => $isActive,
],
],
], [
'upsert' => false,
]);
}
}

protected function setUp()
{
$this->collection = (new MongoTestHelper())->selectCollection('eventStore');
$this->collection->deleteMany([]);
$this->_id = new ObjectID('47ecbc36e8fb4b50662adcf9');
}
}

关于mongodb - 如何在 mongodb 中进行条件更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49194045/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com