public function insert(array $data) { $result = $this->collection->insertOne($data); $id = (string) $result->getInsertedId(); $data['id'] = $id; return $data; }
/** * @param QueryInterface $query * @param ModelInterface $model * @return ModelListInterface * @throws NotSupportedFilterException */ public function find(QueryInterface $query, ModelInterface $model) { $queryArray = array(); foreach ($query->getFilters() as $filter) { if (!in_array(get_class($filter), self::$supportedFilters)) { throw new NotSupportedFilterException(sprintf('%s filter is not supported or unknown.', get_class($filter))); } $queryArray[$filter->getFieldName()] = $filter->getValue(); } $options = array(); if ($query->getLimit() !== null) { $options['limit'] = $query->getLimit(); } if ($query->getOffset() !== null) { $options['skip'] = $query->getOffset(); } $list = new ModelList(); $cursor = $this->collection->find($queryArray, $options); /** @var \MongoDB\Model\BSONDocument $doc */ foreach ($cursor as $doc) { $docArray = (array) $doc; unset($docArray['_id']); /** @var ModelInterface $item */ $item = new $model(); $item->loadData($docArray); if ($item instanceof SavableModelInterface) { $item->markAsStored(); } $list->addListItem($item); } return $list; }
/** * Handle dynamic method calls. * * @param string $method * @param array $parameters * @return mixed */ public function __call($method, $parameters) { $start = microtime(true); $result = call_user_func_array([$this->collection, $method], $parameters); if ($this->connection->logging()) { // Once we have run the query we will calculate the time that it took to run and // then log the query, bindings, and execution time so we will report them on // the event that the developer needs them. We'll log time in milliseconds. $time = $this->connection->getElapsedTime($start); $query = []; // Convert the query parameters to a json string. array_walk_recursive($parameters, function (&$item, $key) { if ($item instanceof ObjectID) { $item = (string) $item; } }); // Convert the query parameters to a json string. foreach ($parameters as $parameter) { try { $query[] = json_encode($parameter); } catch (Exception $e) { $query[] = '{...}'; } } $queryString = $this->collection->getCollectionName() . '.' . $method . '(' . implode(',', $query) . ')'; $this->connection->logQuery($queryString, [], $time); } return $result; }
/** * Drop the collection if it exists. * * @param Collection $collection */ protected function dropCollectionIfItExists(Collection $collection) { $database = new Database($this->manager, $collection->getDatabaseName()); $collections = $database->listCollections(array('filter' => array('name' => $collection->getCollectionName()))); if (iterator_count($collections) > 0) { $this->assertCommandSucceeded($collection->drop()); } }
/** * @param string $sagaType * @param array $associationValue * @return string[] */ public function find(string $sagaType, array $associationValue) : array { $sagas = $this->collection->find(['type' => $sagaType, 'associations' => $associationValue]); return array_map(function (BSONDocument $sagaData) : string { $sagaDataArray = $sagaData->getArrayCopy(); return $sagaDataArray['identity']; }, $sagas->toArray()); }
public function createIndexes() { try { $this->collection->dropIndexes(); } catch (RuntimeException $e) { } $this->collection->createIndex(['timestamp' => 1], ['expireAfterSeconds' => 302]); $this->collection->createIndex(['sessionId' => 1], ['unique' => false]); }
/** * {@inheritdoc} */ public function purge() { if ($this->collection instanceof \MongoDB\Collection) { $this->collection->deleteMany(['expiration' => ['$lte' => time()]]); } else { $this->collection->remove(['expiration' => ['$lte' => time()]], ['multiple' => true]); } return true; }
public function tearDown() { foreach (['fs.files', 'fs.chunks'] as $collection) { $col = new Collection($this->manager, $this->getDatabaseName(), $collection); $col->drop(); } if ($this->hasFailed()) { return; } }
/** * Construct accepts actual objects rather than strings as this class is a delegate of * Tripod and should inherit connections set up there * @param string $storeName * @param Collection $collection * @param string $defaultContext * @param \Tripod\ITripodStat|null $stat * @param string $readPreference */ public function __construct($storeName, Collection $collection, $defaultContext, $stat = null, $readPreference = ReadPreference::RP_PRIMARY) { $this->labeller = new Labeller(); $this->storeName = $storeName; $this->collection = $collection; $this->podName = $collection->getCollectionName(); $this->defaultContext = $defaultContext; $this->stat = $stat; $this->readPreference = $readPreference; }
/** * Persists participation in MongoDB * * @param string $userIdentifier Web user unique identification * @param string $scenarioIdentifier Scenario where tests has been executed (ie. url) * * @return boolean */ public function store($userIdentifier, $scenarioIdentifier) { if (empty($this->participations)) { return false; } $documents = []; $uniqueRunIdentifier = uniqid('', true); foreach ($this->participations as $testIdentifier => $variantIdentifier) { $document = ['testIdentifier' => $testIdentifier, 'variantIdentifier' => $variantIdentifier, 'userIdentifier' => $userIdentifier, 'scenarioIdentifier' => $scenarioIdentifier, 'runIdentifier' => $uniqueRunIdentifier, 'createdAt' => new \MongoDB\BSON\UTCDatetime(time() * 1000)]; $documents[] = ['insertOne' => [$document]]; } $result = $this->collection->bulkWrite($documents); return $result->getInsertedCount(); }
/** * Ensure index of correct specification and a unique name whether the specification or name already exist or not. * Will not create index if $index is a prefix of an existing index * * @param array $index index to create in same format as \MongoDB\Collection::createIndex() * * @return void * * @throws \Exception couldnt create index after 5 attempts */ private function ensureIndex(array $index) { //if $index is a prefix of any existing index we are good foreach ($this->collection->listIndexes() as $existingIndex) { $slice = array_slice($existingIndex['key'], 0, count($index), true); if ($slice === $index) { return; } } for ($i = 0; $i < 5; ++$i) { for ($name = uniqid(); strlen($name) > 0; $name = substr($name, 0, -1)) { //creating an index with same name and different spec does nothing. //creating an index with same spec and different name does nothing. //so we use any generated name, and then find the right spec after we have called, //and just go with that name. try { $this->collection->createIndex($index, ['name' => $name, 'background' => true]); } catch (\MongoDB\Exception\Exception $e) { //this happens when the name was too long, let continue } foreach ($this->collection->listIndexes() as $existingIndex) { if ($existingIndex['key'] === $index) { return; } } } } throw new \Exception('couldnt create index after 5 attempts'); //@codeCoverageIgnoreEnd }
/** * Retrieve the cached results of the api $request. * * @param RequestInterface $request A request for which the response may be cached. * * @return ResponseInterface|null */ public function get(RequestInterface $request) { $cached = $this->collection->findOne(['_id' => $request->getUrl()]); if ($cached === null) { return null; } $headers = $cached['headers']; if ($headers instanceof BSONArray) { $headers = $headers->getArrayCopy(); } $body = $cached['body']; if ($body instanceof BSONArray) { $body = $body->getArrayCopy(); } return new Response($cached['httpCode'], $headers, $body); }
public function testAggregateWithOut() { $server = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY)); if (!\MongoDB\server_supports_feature($server, self::$wireVersionForOutOperator)) { $this->markTestSkipped('$out aggregation pipeline operator is not supported'); } $outputCollection = new Collection($this->manager, $this->getDatabaseName(), $this->getCollectionName() . '_output'); $operation = new DropCollection($this->getDatabaseName(), $outputCollection->getCollectionName()); $operation->execute($this->getPrimaryServer()); $this->collection->aggregate([['$sort' => ['x' => 1]], ['$match' => ['_id' => ['$gt' => 1]]], ['$out' => $outputCollection->getCollectionName()]]); $expected = [['_id' => 2, 'x' => 22], ['_id' => 3, 'x' => 33]]; $this->assertSameDocuments($expected, $outputCollection->find()); // Manually clean up our output collection $operation = new DropCollection($this->getDatabaseName(), $outputCollection->getCollectionName()); $operation->execute($this->getPrimaryServer()); }
/** * Updates a document and returns it. * @param array $condition query condition * @param array $update update criteria * @param array $fields fields to be returned * @param array $options list of options in format: optionName => optionValue. * @return array|null the original document, or the modified document when $options['new'] is set. * @throws Exception on failure. * @see http://www.php.net/manual/en/mongocollection.findandmodify.php */ public function findAndModify($condition, $update, $options = []) { $token = "mongoyii\\" . $this->collection->getCollectionName() . ".findAndModify({\$condition: " . json_encode($condition) . ", \$update: " . json_encode($update) . ", \$options: " . json_encode($options) . " })"; Yii::trace($token, "mongoyii\\Collection"); if ($this->client->enableProfiling) { Yii::beginProfile($token, 'mongoyii\\Collection.findAndModify'); } try { if (isset($options['remove']) && $options['remove']) { $result = $this->collection->findOneAndDelete($condition, $options); } elseif (isset($options['update']) && $options['update']) { if (isset($options['upsert']) && $options['upsert']) { $result = $this->collection->findOneAndReplace($condition, $update, $options); } else { $result = $this->collection->findOneAndUpdate($condition, $update, $options); } } else { throw new Exception('Must enter a operation type for findAndModify'); } if ($this->client->enableProfiling) { Yii::endProfile($token, 'mongoyii\\Collection.findAndModify'); } return $result; } catch (\Exception $e) { if ($this->client->enableProfiling) { Yii::endProfile($token, 'mongoyii\\Collection.findAndModify'); } throw new Exception($e->getMessage(), (int) $e->getCode(), $e); } }
public function fetch(CriteriaManager $criteriaManager, Collection $collection) : array { $order = 1; $filter = []; $options = ['limit' => self::DEFAULT_LIMIT]; $criteriaManager->doWith(SortCriteria::class, function (SortCriteria $criteria) use(&$options, &$order) { $order = strtolower($criteria->getOrder()) === 'asc' ? 1 : -1; $options['sort'] = []; $options['sort'][$criteria->getField()] = $order; }); $criteriaManager->doWith(SeekCriteria::class, function (SeekCriteria $criteria) use(&$options, &$filter, $order) { $options['limit'] = $criteria->getLimit(); $options['skip'] = 0; if ($criteria->getLastId()) { $lastId = new ObjectID($criteria->getLastId()); if ($order === 1) { $filter['_id'] = ['$gt' => $lastId]; } else { $filter['_id'] = ['$lt' => $lastId]; } } }); $criteriaManager->doWith(ThemeIdCriteria::class, function (ThemeIdCriteria $criteria) use(&$filter) { $filter[sprintf('theme_ids.%s', (string) $criteria->getThemeId())] = ['$exists' => true]; }); $criteriaManager->doWith(QueryStringCriteria::class, function (QueryStringCriteria $criteria) use(&$filter) { if ($criteria->isAvailable()) { $filter['$text'] = ['$search' => $criteria->getQuery()]; } }); $cursor = $collection->find($filter, $options)->toArray(); if (count($cursor)) { $this->profileService->loadProfilesByIds(array_map(function (BSONDocument $document) { return (int) $document['id']; }, $cursor)); return $this->cleanResults(array_map(function (BSONDocument $document) { try { $profile = $this->profileService->getProfileById((int) $document['id']); return array_merge(['_id' => (string) $document['_id']], $profile->toJSON()); } catch (ProfileNotFoundException $e) { return null; } }, $cursor)); } else { return []; } }
/** * @param array $filter * @param array $options * * @return \Traversable */ public function find(array $filter = [], array $options = []) { $cursor = $this->collection->find($filter, $options); $cursor->setTypeMap(['root' => 'array', 'document' => 'array', 'array' => 'array']); foreach ($cursor as $values) { (yield $this->hydrator->hydrate($values)); } }
/** * @param array $criteria * @param int $offset * @param int $limit * @return Document[] */ public function findBy(array $criteria, int $offset = 0, int $limit = 500) : array { $cursor = $this->collection->find($criteria, ['skip' => $offset, 'limit' => $limit]); return array_map(function (BSONDocument $document) : Document { $data = $document->getArrayCopy(); unset($data['_id']); return $this->converter->arrayToObject($data, $this->documentClass); }, $cursor->toArray()); }
/** * @return \MongoDB\Collection */ private function createCollectionObject() { $options = ['readPreference' => $this->readPreference, 'writeConcern' => $this->writeConcern]; if ($this->collection === null) { $this->collection = $this->db->getDb()->selectCollection($this->name, $options); } else { $this->collection = $this->collection->withOptions($options); } }
/** * Garbage collection * * Note: MongoDB 2.2+ supports TTL collections, which may be used in place * of this method by indexing the "modified" field with an * "expireAfterSeconds" option. Regardless of whether TTL collections are * used, consider indexing this field to make the remove query more * efficient. * * @see http://docs.mongodb.org/manual/tutorial/expire-data/ * @param int $maxlifetime * @return bool */ public function gc($maxlifetime) { /* Note: unlike DbTableGateway, we do not use the lifetime field in * each document. Doing so would require a $where query to work with the * computed value (modified + lifetime) and be very inefficient. */ $microseconds = floor(microtime(true) * 1000) - $maxlifetime; $result = $this->mongoCollection->deleteMany([$this->options->getModifiedField() => ['$lt' => new UTCDateTime($microseconds)]], $this->options->getSaveOptions()); return $result->isAcknowledged(); }
public function testSeeElementIsObjectThrowsError() { $trumpet = new \StdClass(); $trumpet->name = 'Trumpet 1'; $trumpet->pitch = 'B♭'; $trumpet->price = array('min' => 458, 'max' => 891); $this->setExpectedException('PHPUnit_Framework_ExpectationFailedException'); $this->userCollection->insertOne(array('id' => 5, 'trumpet' => $trumpet)); $this->userCollection->insertOne(array('id' => 6, 'trumpet' => $trumpet)); $this->module->seeElementIsObject('users', array(), 'trumpet'); }
/** * {@inheritdoc} */ public function keys() { try { $cursor = $this->collection->find(array(), array('projection' => array('_id' => 1))); $keys = array(); foreach ($cursor as $document) { $keys[] = $document['_id']; } } catch (Exception $e) { throw ReadException::forException($e); } return $keys; }
/** * * @return array */ public function getDatasetRaces() { return $this->cacheGet('pie/races/', function () { $data = [Character::RACE_ASURA => ['y' => 0, 'name' => $this->trans('race.' . Character::RACE_ASURA)], Character::RACE_CHARR => ['y' => 0, 'name' => $this->trans('race.' . Character::RACE_CHARR)], Character::RACE_HUMAN => ['y' => 0, 'name' => $this->trans('race.' . Character::RACE_HUMAN)], Character::RACE_NORN => ['y' => 0, 'name' => $this->trans('race.' . Character::RACE_NORN)], Character::RACE_SYLVARI => ['y' => 0, 'name' => $this->trans('race.' . Character::RACE_SYLVARI)]]; foreach ($this->collection->find() as $row) { if (isset($row['race'])) { foreach ($row['race'] as $key => $value) { $data[$key]['y'] += $value; } } } return array_values($data); }, 4 * 3600); }
/** * Assert that the collections contain equivalent documents. * * This method will resolve references within the expected collection's * documents before comparing documents. Occurrences of "*result" in the * expected collection's documents will be replaced with the actual result. * Occurrences of "*actual" in the expected collection's documents will be * replaced with the corresponding value in the actual collection's document * being compared. * * @param Collection $expectedCollection * @param Collection $actualCollection * @param mixed $actualResult */ private function assertEquivalentCollections($expectedCollection, $actualCollection, $actualResult) { $mi = new MultipleIterator(); $mi->attachIterator(new IteratorIterator($expectedCollection->find())); $mi->attachIterator(new IteratorIterator($actualCollection->find())); foreach ($mi as $documents) { list($expectedDocument, $actualDocument) = $documents; array_walk($expectedDocument, function (&$value) use($actualResult) { if ($value === '*result') { $value = $actualResult; } }); array_walk($expectedDocument, function (&$value, $key) use($actualDocument) { if (!is_string($value)) { return; } if (!strncmp($value, '*actual_', 8)) { $value = $actualDocument[$key]; } }); $this->assertSameDocument($expectedDocument, $actualDocument); } }
/** * Returns the array containing all cities in a country. * * @author Shivam Mathur <*****@*****.**> * * @param $countryName * @param bool $test * @return array * @throws \Exception */ private function cities($countryName, $test = false) { if ($countryName == '_id') { throw new \Exception('Could not found the country - ' . $countryName); } $locationData = []; if (!$test) { $locationData = $this->database->findOne([], ['projection' => ['_id' => false, $countryName => true], 'typeMap' => ['root' => 'array', 'document' => 'array']]); } if (!$locationData) { throw new \Exception('Could not found the country - ' . $countryName); } // Getting names of cities from $locationData $cities = $locationData[$countryName]; sort($cities); return $cities; }
public function ensureIndexes(Database $database, Collection $collection) { $collection->createIndex(['title' => 'text']); }
/** * Ensure $indexToEnsure on the given mongo $collection * @param Collection $collection * @param array $indexToEnsure */ protected function ensureIndex(Collection $collection, array $indexToEnsure) { $collection->createIndex($indexToEnsure, array('background' => 1)); }
public static function createCollection(Manager $manager, $namespace) { $collection = new Collection($manager, $namespace); $collection->createIndex(['expireAt' => 1], ['expireAfterSeconds' => 0]); return $collection; }
/** * @param Result $result * @return \MongoDB\InsertOneResult */ public function save(Result $result) { $document = ['url' => $result->getUrl(), 'modifiedSince' => $result->getModifiedSince(), 'feed' => $result->getFeed()->toArray()]; return $this->collection->insertOne($document); }
/** * @param array $data * @param string $id * @param int $keyType * @param string $rootId * @param string $property * @return string */ protected function update($data, $id, $keyType, $rootId, $property) { CodeGuard::checkTypeAndThrow($rootId, 'string'); CodeGuard::checkTypeAndThrow($id, 'string'); if ($keyType == self::ID_IN_KEY) { if (empty($rootId)) { $mongoid = self::mongoID($id); $filter = array('_id' => $mongoid); $updateCommand = array('$set' => $data); $options = array('upsert' => true); $this->_collection->updateOne($filter, $updateCommand, $options); $id = $mongoid->__toString(); } else { CodeGuard::checkNullAndThrow($id, 'id'); CodeGuard::checkNullAndThrow($property, 'property'); $subKey = $property . '.' . $id; $filter = array('_id' => self::mongoID($rootId)); $updateCommand = array('$set' => array($subKey => $data)); $this->_collection->updateOne($filter, $updateCommand); } } else { CodeGuard::checkNullAndThrow($id, 'id'); $filter = array('_id' => self::mongoID($rootId)); $updateCommand = array('$set' => array($property . '$' . $id => $data)); $this->_collection->updateOne($filter, $updateCommand); } return $id; }
/** * @param string $cbdSubject * @param MongoGraph $cbdGraph * @param Collection $collection * @param string $context * @throws \Exception */ protected function saveCBD($cbdSubject, MongoGraph $cbdGraph, Collection $collection, $context) { $cbdSubject = $this->labeller->uri_to_alias($cbdSubject); if ($cbdGraph == null || $cbdGraph->is_empty()) { throw new \Exception("graph for {$cbdSubject} was null"); } try { $collection->insertOne($cbdGraph->to_tripod_array($cbdSubject, $context), array("w" => 1)); print "."; } catch (\Exception $e) { if (preg_match('/E11000/', $e->getMessage())) { print "M"; // key already exists, merge it $criteria = array("_id" => array("r" => $cbdSubject, "c" => $context)); $existingGraph = new MongoGraph(); $existingGraph->add_tripod_array($collection->findOne($criteria)); $existingGraph->add_graph($cbdGraph); try { $collection->updateOne($criteria, ['$set' => $existingGraph->to_tripod_array($cbdSubject, $context)], array("w" => 1)); } catch (\Exception $e2) { throw new \Exception($e2->getMessage()); // todo: would be good to have typed exception } } else { // retry print "CursorException on update: " . $e->getMessage() . ", retrying\n"; try { $collection->insertOne($cbdGraph->to_tripod_array($cbdSubject, $context), array("w" => 1)); } catch (\Exception $e2) { throw new \Exception($e2->getMessage()); // todo: would be good to have typed exception } } } }