Skip to content

Instantly share code, notes, and snippets.

@alistaircol
Created September 12, 2020 10:50
Show Gist options
  • Save alistaircol/227b7d3768e559b944fb65265a6c6179 to your computer and use it in GitHub Desktop.
Save alistaircol/227b7d3768e559b944fb65265a6c6179 to your computer and use it in GitHub Desktop.
MongoDB & PHP Integration
<?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