public function testExtended()
 {
     $query = new QueryString('foo bar');
     $filter = new Query($query);
     $filter->setCached(true);
     $expected = array('fquery' => array('query' => array('query_string' => array('query' => 'foo bar')), '_cache' => true));
     $this->assertEquals($expected, $filter->toArray());
 }
 /**
  * If there is any boosting to be done munge the the current query to get it right.
  */
 private function installBoosts()
 {
     // Quick note:  At the moment ".isEmpty()" is _much_ faster then ".empty".  Never
     // use ".empty".  See https://github.com/elasticsearch/elasticsearch/issues/5086
     if ($this->sort !== 'relevance') {
         // Boosts are irrelevant if you aren't sorting by, well, relevance
         return;
     }
     $functionScore = new \Elastica\Query\FunctionScore();
     $useFunctionScore = false;
     // Customize score by boosting based on incoming links count
     if ($this->boostLinks) {
         $useFunctionScore = true;
         if ($this->config->getElement('CirrusSearchWikimediaExtraPlugin', 'field_value_factor_with_default')) {
             $functionScore->addFunction('field_value_factor_with_default', array('field' => 'incoming_links', 'modifier' => 'log2p', 'missing' => 0));
         } else {
             $scoreBoostExpression = "log10(doc['incoming_links'].value + 2)";
             $functionScore->addScriptScoreFunction(new \Elastica\Script($scoreBoostExpression, null, 'expression'));
         }
     }
     // Customize score by decaying a portion by time since last update
     if ($this->preferRecentDecayPortion > 0 && $this->preferRecentHalfLife > 0) {
         // Convert half life for time in days to decay constant for time in milliseconds.
         $decayConstant = log(2) / $this->preferRecentHalfLife / 86400000;
         $parameters = array('decayConstant' => $decayConstant, 'decayPortion' => $this->preferRecentDecayPortion, 'nonDecayPortion' => 1 - $this->preferRecentDecayPortion, 'now' => time() * 1000);
         // e^ct where t is last modified time - now which is negative
         $exponentialDecayExpression = "exp(decayConstant * (doc['timestamp'].value - now))";
         if ($this->preferRecentDecayPortion !== 1.0) {
             $exponentialDecayExpression = "{$exponentialDecayExpression} * decayPortion + nonDecayPortion";
         }
         $functionScore->addScriptScoreFunction(new \Elastica\Script($exponentialDecayExpression, $parameters, 'expression'));
         $useFunctionScore = true;
     }
     // Add boosts for pages that contain certain templates
     if ($this->boostTemplates) {
         foreach ($this->boostTemplates as $name => $boost) {
             $match = new \Elastica\Query\Match();
             $match->setFieldQuery('template', $name);
             $filterQuery = new \Elastica\Filter\Query($match);
             $filterQuery->setCached(true);
             $functionScore->addBoostFactorFunction($boost, $filterQuery);
         }
         $useFunctionScore = true;
     }
     // Add boosts for namespaces
     $namespacesToBoost = $this->namespaces ?: MWNamespace::getValidNamespaces();
     if ($namespacesToBoost) {
         // Group common weights together and build a single filter per weight
         // to save on filters.
         $weightToNs = array();
         foreach ($namespacesToBoost as $ns) {
             $weight = $this->getBoostForNamespace($ns);
             $weightToNs[(string) $weight][] = $ns;
         }
         if (count($weightToNs) > 1) {
             unset($weightToNs['1']);
             // That'd be redundant.
             foreach ($weightToNs as $weight => $namespaces) {
                 $filter = new \Elastica\Filter\Terms('namespace', $namespaces);
                 $functionScore->addBoostFactorFunction($weight, $filter);
                 $useFunctionScore = true;
             }
         }
     }
     // Boost pages in a user's language
     $userLang = $this->config->getUserLanguage();
     $userWeight = $this->config->getElement('CirrusSearchLanguageWeight', 'user');
     if ($userWeight) {
         $functionScore->addBoostFactorFunction($userWeight, new \Elastica\Filter\Term(array('language' => $userLang)));
         $useFunctionScore = true;
     }
     // And a wiki's language, if it's different
     $wikiWeight = $this->config->getElement('CirrusSearchLanguageWeight', 'wiki');
     if ($userLang != $this->config->get('LanguageCode') && $wikiWeight) {
         $functionScore->addBoostFactorFunction($wikiWeight, new \Elastica\Filter\Term(array('language' => $this->config->get('LanguageCode'))));
         $useFunctionScore = true;
     }
     if (!$useFunctionScore) {
         // Nothing to do
         return;
     }
     // The function score is done as a rescore on top of everything else
     $this->rescore[] = array('window_size' => $this->config->get('CirrusSearchFunctionRescoreWindowSize'), 'query' => array('rescore_query' => $functionScore, 'query_weight' => 1.0, 'rescore_query_weight' => 1.0, 'score_mode' => 'multiply'));
 }
 public function attributeAction()
 {
     $result = ['outcome' => 0];
     $entityClass = 'Lead\\Entity\\LeadAttribute';
     $id = $this->getEvent()->getRouteMatch()->getParam('id', '0');
     $action = $this->params()->fromQuery('action', 'update');
     $em = $this->getEntityManager();
     $objRepository = $em->getRepository($entityClass);
     if ($id) {
         switch ($action) {
             case 'update':
                 $attributeType = $this->params()->fromQuery('type', false);
                 if ($attributeType) {
                     /* @var $entity \Lead\Entity\LeadAttribute */
                     $entity = $objRepository->find($id);
                     if ($entity && $entity instanceof $entityClass) {
                         $entity->setAttributeType($attributeType);
                         try {
                             $em->persist($entity);
                             $em->flush();
                             $this->createServiceEvent()->setEntityId($id)->setEntityClass($entityClass)->setDescription("Lead Attribute Edited")->setMessage("Lead Attribute: " . $entity->getAttributeDesc() . " was edited.");
                             $this->logEvent("EditAction.post");
                             $result['outcome'] = 1;
                         } catch (\Exception $e) {
                             $this->createServiceEvent()->setEntityId($id)->setEntityClass($entityClass)->setDescription("Lead Attribute Edited");
                             $this->logError($e);
                         }
                     }
                 }
                 break;
             case 'relationship':
                 /* @var $entity \Lead\Entity\LeadAttribute */
                 $entity = $objRepository->find($id);
                 if ($entity && $entity instanceof $entityClass) {
                     $attributeType = $entity->getAttributeType();
                     /* @var $qb \Doctrine\ORM\QueryBuilder */
                     $qb = $em->createQueryBuilder();
                     $qb->add('select', 'e')->add('from', 'Agent\\Entity\\Relationship' . ' e')->where(' e.allowed LIKE :attributeType')->setParameter('attributeType', "%" . $attributeType . "%");
                     $dql = $qb->getDQL();
                     $query = $qb->getQuery();
                     $query->useQueryCache(true);
                     $query->useResultCache(true, 3600, 'relationship-' . md5($dql));
                     $result['data'] = $query->getArrayResult();
                     $result['outcome'] = 1;
                 }
                 break;
             case 'values':
                 $qb = $em->createQueryBuilder()->select('v.value')->from('Lead\\Entity\\LeadAttributeValue', 'v')->where('v.attribute = :id')->setParameter('id', $id)->distinct(true);
                 $dql = $qb->getDQL();
                 $query = $qb->getQuery();
                 $query->useQueryCache(true);
                 $query->useResultCache(true, 3600, 'leadattributevalue-' . md5($dql));
                 $results = $query->getArrayResult();
                 if ($results) {
                     $result['data'] = $results;
                     $result['outcome'] = 1;
                 }
                 break;
             case 'limits':
                 $attribute_query = new Elastica\Query\Nested();
                 $attribute_query->setPath('attribute');
                 $attribute_query->setQuery(new Elastica\Query\Match('attribute.id', $id));
                 $value_filter = new Elastica\Filter\Query();
                 $value_filter->setQuery($attribute_query);
                 $max = new Elastica\Aggregation\Max('max_number');
                 $max->setField('_number');
                 $min = new Elastica\Aggregation\Min('min_number');
                 $min->setField('_number');
                 $aggs = new Elastica\Aggregation\Filter('numeric_range', $value_filter);
                 $aggs->addAggregation($max)->addAggregation($min);
                 $query = new Elastica\Query();
                 $query->setSize(0);
                 $query->addAggregation($aggs);
                 /* @var $elastica_client Elastica\Client */
                 $elastica_client = $this->getServiceLocator()->get('elastica-client');
                 $result['query'] = $query->toArray();
                 try {
                     /* @var $response \Elastica\Response */
                     $response = $elastica_client->request('reports/value/_search', Request::GET, $query->toArray());
                     $data = $response->getData();
                     $limits = ['min' => 0, 'max' => 0];
                     if (isset($data['aggregations']['numeric_range']) && $data['aggregations']['numeric_range']['doc_count'] > 0) {
                         $limits['min'] = $data['aggregations']['numeric_range']['min_number']['value'];
                         $limits['max'] = $data['aggregations']['numeric_range']['max_number']['value'];
                     }
                     $result['data'] = $limits;
                     $result['outcome'] = 1;
                 } catch (\Exception $e) {
                     $result['error'] = $e->getMessage();
                 }
                 break;
         }
     }
     return new JsonModel($result);
 }