Created
September 12, 2020 10:50
-
-
Save alistaircol/227b7d3768e559b944fb65265a6c6179 to your computer and use it in GitHub Desktop.
MongoDB & PHP Integration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use MongoDB\BSON\ObjectId; | |
use MongoDB\Collection; | |
use MongoDB\Database; | |
use MongoDB\Model\BSONDocument; | |
class SemiUnstructuredData | |
{ | |
public function testMongodb() | |
{ | |
// qa_mongo is local container name | |
$mongodb_username = 'root'; | |
$mongodb_password = 'example'; | |
$mongodb_host = 'ac_mongodb'; | |
$mongodb_port = 27017; | |
$client = new MongoDB\Client(vsprintf( | |
'mongodb://%s:%s@%s:%s', | |
[ | |
$mongodb_username, | |
$mongodb_password, | |
$mongodb_host, | |
$mongodb_port, | |
] | |
)); | |
$collection = $client | |
->selectDatabase('alistaircol') | |
->selectCollection('policy_data'); | |
// get & edit | |
$source = $this->getPolicy($collection, '5f5c0825d981e47292feb25c'); | |
$target = $source; | |
$target['DATE_PAID'] = DateTime::createFromFormat('d/m/Y', $target['DATE_PAID']) | |
->modify('+1 days') | |
->format('d/m/Y'); | |
$this->revise($collection, $source, $target); | |
// search to get all values for ui grid headers, you should cache this | |
$prefixes = $this->getPrefixes($collection); | |
$products = $this->getProducts($collection); | |
// search from ui grid | |
$filters = [ | |
// Note: The pattern should not be wrapped with delimiter characters. | |
// for flags: https://docs.mongodb.com/manual/reference/operator/query/regex/#op._S_options | |
'ADDRESS_LINE_1' => (new MongoDB\BSON\Regex('road', 'i')), | |
]; | |
$page_size = 20; | |
$page = 1; | |
$skip = ($page - 1) * $page_size; | |
$options = [ | |
'projection' => [ | |
'_id' => true, | |
'ADDRESS_LINE_1' => true, | |
'ADDRESS_POST_CODE' => true, | |
'SURNAME' => true, | |
'PREFIX' => true, | |
'ENTRY' => true, | |
'PRODUCT' => true, | |
'CONTRACTOR' => true, | |
], | |
'limit' => $page_size, | |
'skip' => $skip, | |
// sort => ['field' => -1], | |
]; | |
$documents = $this->queryDocuments($collection, $filters, $options); | |
$count = $this->queryCollectionCount($collection, $filters); | |
} | |
/** | |
* The number of documents in the collection matching $filter criteria. | |
* | |
* @param Collection $collection | |
* @param array $filter | |
* @return int | |
*/ | |
private function queryCollectionCount(Collection $collection, array $filter): int | |
{ | |
/** @var ArrayIterator $response */ | |
$response = $collection->aggregate([ | |
['$match' => $filter], | |
['$count' => 'total'], | |
]); | |
$response = iterator_to_array($response); | |
return $response[0]['total']; | |
} | |
/** | |
* @param Collection $collection | |
* @param array $filter | |
* @param array $options | |
* @return array | |
*/ | |
private function queryCollection(Collection $collection, array $filter, array $options): array | |
{ | |
return $collection->find($filter, $options)->toArray(); | |
} | |
/** | |
* Query the collection to get all distinct PREFIXes. | |
* | |
* @param Collection $collection | |
* @param string $column_name | |
* @return array | |
*/ | |
private function getPrefixes(Collection $collection, string $column_name = 'PREFIX'): array | |
{ | |
return $this->getDistinctValues($collection, $column_name); | |
} | |
/** | |
* Query the collection to get all distinct SCHEMEs. | |
* | |
* @param Collection $collection | |
* @param string $column_name | |
* @return array | |
*/ | |
private function getSchemes(Collection $collection, string $column_name = 'SCHEME'): array | |
{ | |
return $this->getDistinctValues($collection, $column_name); | |
} | |
/** | |
* Utility to get all distinct values for $column_name. | |
* | |
* @param Collection $collection | |
* @param string $column_name | |
* @return array | |
*/ | |
private function getDistinctValues(Collection $collection, string $column_name): array | |
{ | |
$response = $collection->aggregate([ | |
[ | |
'$group' => [ | |
'_id' => sprintf('$%s', $column_name) | |
] | |
], | |
[ | |
'$sort' => [ | |
'_id' => 1 | |
] | |
], | |
]); | |
$columns = []; | |
foreach ($response as $document) { | |
$column = $document->_id; | |
$columns[$column] = $column; | |
} | |
return $columns; | |
} | |
/** | |
* Get a document in the collection with $object_id. | |
* | |
* @param Collection $collection | |
* @param string $object_id | |
* @return array | |
*/ | |
private function getPolicy(Collection $collection, string $object_id): array | |
{ | |
$response = $collection->findOne( | |
[ | |
'_id' => new ObjectId($object_id), | |
] | |
); | |
/** @var BSONDocument $document */ | |
$document = $response->jsonSerialize(); | |
$result = (array) $document; | |
// convert Bson\ObjectId to str | |
$result['_id'] = $object_id; | |
return $result; | |
} | |
/** | |
* Update $old_document to $new_document in $collection. | |
* | |
* @param Collection $collection | |
* @param array $old_document | |
* @param array $new_document | |
* @return bool | |
*/ | |
private function reviseDocument(Collection $collection, array $old_document, array $new_document): bool | |
{ | |
$object_id = new ObjectId($old_document['_id']); | |
$new_document['_id'] = $object_id; | |
// TODO: get diff and update in MYSQL DB | |
$result = $collection->updateOne( | |
[ | |
'_id' => $object_id | |
], | |
[ | |
'$set' => $new_document | |
] | |
); | |
// maybe ues $result->getMatchedCount(); instead | |
// incase our diff check is crap | |
return $result->getModifiedCount() == 1; | |
} | |
/** | |
* Query $collection for documents matching $filters with $options. | |
* | |
* @param Collection $collection | |
* @param array $filters | |
* @param array $options | |
* @return array | |
*/ | |
private function queryDocuments(Collection $collection, array $filters, array $options): array | |
{ | |
$cursor = $collection->find($filters, $options); | |
return $cursor->toArray(); | |
} | |
/** | |
* Delete $object_id from $collection. | |
* | |
* @param Collection $collection | |
* @param string $object_id | |
* @return bool | |
*/ | |
public function deleteDocument(Collection $collection, string $object_id): bool | |
{ | |
$response = $collection->deleteOne( | |
[ | |
'_id' => new ObjectId($object_id), | |
] | |
); | |
return $response->getDeletedCount() == 1; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment