/** * Returns the ids of all documents that contain and impact index entry * matching the resource and context specified * @param array $resourcesAndPredicates * @param string $context * @return array the ids of search documents that had matching entries in their impact index */ public function findImpactedDocuments(array $resourcesAndPredicates, $context) { $contextAlias = $this->labeller->uri_to_alias($context); $specPredicates = array(); foreach ($this->config->getSearchDocumentSpecifications($this->storeName) as $spec) { if (isset($spec[_ID_KEY])) { $specPredicates[$spec[_ID_KEY]] = $this->config->getDefinedPredicatesInSpec($this->storeName, $spec[_ID_KEY]); } } // build a filter - will be used for impactIndex detection and finding search types to re-gen $searchDocFilters = array(); $resourceFilters = array(); foreach ($resourcesAndPredicates as $resource => $resourcePredicates) { $resourceAlias = $this->labeller->uri_to_alias($resource); $id = array(_ID_RESOURCE => $resourceAlias, _ID_CONTEXT => $contextAlias); // If we don't have a working config or there are no predicates listed, remove all // rows associated with the resource in all search types if (empty($specPredicates) || empty($resourcePredicates)) { // build $filter for queries to impact index $resourceFilters[] = $id; } else { foreach ($specPredicates as $searchDocType => $predicates) { // Only look for search rows if the changed predicates are actually defined in the searchDocspec if (array_intersect($resourcePredicates, $predicates)) { if (!isset($searchDocFilters[$searchDocType])) { $searchDocFilters[$searchDocType] = array(); } // build $filter for queries to impact index $searchDocFilters[$searchDocType][] = $id; } } } } $searchTypes = array(); if (empty($searchDocFilters) && !empty($resourceFilters)) { $query = array(_IMPACT_INDEX => array('$in' => $resourceFilters)); } else { $query = array(); foreach ($searchDocFilters as $searchDocType => $filters) { // first re-gen views where resources appear in the impact index $query[] = array(_IMPACT_INDEX => array('$in' => $filters), '_id.' . _ID_TYPE => $searchDocType); $searchTypes[] = $searchDocType; } if (!empty($resourceFilters)) { $query[] = array(_IMPACT_INDEX => array('$in' => $resourceFilters)); } if (count($query) === 1) { $query = $query[0]; } elseif (count($query) > 1) { $query = array('$or' => $query); } } if (empty($query)) { return array(); } $searchDocs = array(); foreach ($this->config->getCollectionsForSearch($this->storeName, $searchTypes) as $collection) { $cursor = $collection->find($query, array('projection' => array('_id' => true))); foreach ($cursor as $d) { $searchDocs[] = $d; } } return $searchDocs; }