/** * * @param BoolQuery $lead_query * @param AgentCriterion $criterion * * @return BoolQuery $lead_query */ protected function buildQuery(BoolQuery $lead_query, AgentCriterion $criterion) { if (!$criterion->getServiceLocator()) { $criterion->setServiceLocator($this->getServiceLocator()); } $criteria_query = false; $relationship = $criterion->getRelationship(); $required = $criterion->getRequired(); $weight = $criterion->getWeight(); if ($relationship) { $value = $criterion->getValue(); if ($value) { $data = $value->getData(); $boost = $weight ? (1 - $weight) * 10 + 1 : 1; $abstractQuery = $relationship->getQuery(); if ($abstractQuery) { $abstractQuery->setCriterion($criterion); $abstractQuery->setRelationship($relationship); $request = $this->getServiceLocator()->get('Request'); $debug = $request->getQuery('debug'); if ($debug) { echo "<script>console.dir(" . json_encode($data) . ");</script>\n"; } $boolQuery = $abstractQuery->getQuery($data, null, $required, $boost); if ($boolQuery) { switch ($relationship->getType()) { case 'location': $queryClass = (new \ReflectionClass($boolQuery))->getShortName(); switch ($queryClass) { case 'GeoDistance': $criteria_query = $boolQuery; break; default: $criteria_query = new Elastica\Query\HasChild($boolQuery, 'value'); $criteria_query->setParam('score_mode', 'avg'); break; } break; default: $criteria_query = new Elastica\Query\HasChild($boolQuery, 'value'); $criteria_query->setParam('score_mode', 'avg'); break; } if ($required) { $lead_query->addMust($criteria_query); } else { $lead_query->addShould($criteria_query); $lead_query->setBoost($boost); } } } } } return $lead_query; }
/** * * @param array $location * * @return Elastica\Query $localityQuery */ public static function getLocalityQuery($location) { $query = new Agent\Elastica\Query\BoolQuery(); $method = 'addMust'; if (!isset($location['state']) && !isset($location['zip']) && !isset($location['locality'])) { foreach (['phone', 'ipaddress'] as $field) { if (isset($location[$field]) && empty($location['state'])) { switch ($field) { case 'ipaddress': $geo = self::$geo; $loc = $geo->getRecord($location['ipaddress']); if ($loc instanceof Record) { $state = $loc->getRegion(); if ($state) { $location['state'] = $state; } } break; case 'phone': $phone = Helper::parse_phonenumber($location['phone'], 'array'); if ($phone) { $state = Helper::area_code_to_state($phone[0]); if ($state) { $location['state'] = $state; } } break; } } } } foreach ($location as $field => $value) { switch ($field) { case 'locality': if (!isset($location['zip'])) { $fields = ['latitude', 'longitude']; $values = is_array($value) ? $value : explode(",", $value); $latlon = count($values) == 2 ? array_combine($fields, $values) : false; if ($latlon) { $path = "location"; $nested = new Elastica\Query\Nested(); $nested->setPath($path); $bool = new Elastica\Query\BoolQuery(); foreach ($latlon as $dim => $coord) { $bool->addMust(new Elastica\Query\Match("{$path}.{$dim}", $coord)); } $nested->setQuery($bool); $query->addMust($nested); } } break; case 'city': if (!isset($location['locality'])) { $query->addShould(new Elastica\Query\Match($field, $value)); } break; case 'state': if (!isset($location['locality'])) { $fields = ['state.abbrev', 'state.full']; $values = is_array($value) ? $value : [$value]; foreach ($values as $state) { $querystring = new Elastica\Query\QueryString($state); $querystring->setFields($fields); $nested = new Elastica\Query\Nested(); $nested->setQuery($querystring); $nested->setPath($field); if (count($values) > 1) { $query->addShould($nested); } else { $query->addMust($nested); } } } break; case 'zip': $query->{$method}(new Elastica\Query\Match($field, $value)); break; } } $localityQuery = new Elastica\Query($query); $localityQuery->setSize(1); return $localityQuery; }