public function testRemoveInvalidSort() { $sorts = array('field1' => Query::SORT_DESC, 'field2' => Query::SORT_ASC); $this->query->addSorts($sorts); $this->query->removeSort('invalidfield'); //continue silently $this->assertEquals($sorts, $this->query->getSorts()); }
/** * Adds spatial features to the search query. */ public function setSpatial(Query $solarium_query, QueryInterface $query, $spatial_options = array(), $field_names) { foreach ($spatial_options as $i => $spatial) { // reset radius for each option unset($radius); if (empty($spatial['field']) || empty($spatial['lat']) || empty($spatial['lon'])) { continue; } $field = $field_names[$spatial['field']]; $escaped_field = SearchApiSolrUtility::escapeFieldName($field); $point = (double) $spatial['lat'] . ',' . (double) $spatial['lon']; // Prepare the filter settings. if (isset($spatial['radius'])) { $radius = (double) $spatial['radius']; } $spatial_method = 'geofilt'; if (isset($spatial['method']) && in_array($spatial['method'], array('geofilt', 'bbox'))) { $spatial_method = $spatial['method']; } $filter_queries = $solarium_query->getFilterQueries(); // Change the fq facet ranges to the correct fq. foreach ($filter_queries as $key => $filter_query) { // If the fq consists only of a filter on this field, replace it with // a range. $preg_field = preg_quote($escaped_field, '/'); if (preg_match('/^' . $preg_field . ':\\["?(\\*|\\d+(?:\\.\\d+)?)"? TO "?(\\*|\\d+(?:\\.\\d+)?)"?\\]$/', $filter_query, $matches)) { unset($filter_queries[$key]); if ($matches[1] && is_numeric($matches[1])) { $min_radius = isset($min_radius) ? max($min_radius, $matches[1]) : $matches[1]; } if (is_numeric($matches[2])) { // Make the radius tighter accordingly. $radius = isset($radius) ? min($radius, $matches[2]) : $matches[2]; } } } // If either a radius was given in the option, or a filter was // encountered, set a filter for the lowest value. If a lower boundary // was set (too), we can only set a filter for that if the field name // doesn't contains any colons. if (isset($min_radius) && strpos($field, ':') === FALSE) { $upper = isset($radius) ? " u={$radius}" : ''; $solarium_query->createFilterQuery($field)->setQuery("{!frange l={$min_radius}{$upper}}geodist({$field},{$point})"); } elseif (isset($radius)) { $solarium_query->createFilterQuery($field)->setQuery("{!{$spatial_method} pt={$point} sfield={$field} d={$radius}}"); } // @todo: Check if this object returns the correct value $sorts = $solarium_query->getSorts(); // Change sort on the field, if set (and not already changed). if (isset($sorts[$spatial['field']]) && substr($sorts[$spatial['field']], 0, strlen($field)) === $field) { $sorts[$spatial['field']] = str_replace($field, "geodist({$field},{$point})", $sorts[$spatial['field']]); } // Change the facet parameters for spatial fields to return distance // facets. $facets = $solarium_query->getFacetSet(); // @todo: Fix this so it takes it from the solarium query if (!empty($facets)) { if (!empty($facet_params['facet.field'])) { $facet_params['facet.field'] = array_diff($facet_params['facet.field'], array($field)); } foreach ($facets as $delta => $facet) { if ($facet['field'] != $spatial['field']) { continue; } $steps = $facet['limit'] > 0 ? $facet['limit'] : 5; $step = (isset($radius) ? $radius : 100) / $steps; for ($k = $steps - 1; $k > 0; --$k) { $distance = $step * $k; $key = "spatial-{$delta}-{$distance}"; $facet_params['facet.query'][] = "{!{$spatial_method} pt={$point} sfield={$field} d={$distance} key={$key}}"; } foreach (array('limit', 'mincount', 'missing') as $setting) { unset($facet_params["f.{$field}.facet.{$setting}"]); } } } } // Normal sorting on location fields isn't possible. foreach (array_keys($solarium_query->getSorts()) as $sort) { if (substr($sort, 0, 3) === 'loc') { $solarium_query->removeSort($sort); } } }