<?php include "bootstrap.php"; $xml_reponse = file_get_contents(EXAMPLE_RESPONSE_XML_1); $solrObject = SolrUtils::digestXMLResponse($xml_reponse); print_r($solrObject->system->threadDump->thread->stackTrace);
<?php include "bootstrap.php"; $options = array('hostname' => SOLR_SERVER_HOSTNAME, 'login' => SOLR_SERVER_USERNAME, 'password' => SOLR_SERVER_PASSWORD, 'port' => SOLR_SERVER_PORT); $client = new SolrClient($options); $query = new SolrQuery(); $userInput = 'USB/2'; $escapedUserInput = SolrUtils::escapeQueryChars($userInput); $query->setQuery('text:' . $escapedUserInput); echo $query . PHP_EOL;
public function findQuery($y_query, $y_options = array('settings' => array(), 'sort' => array(), 'filters' => array(), 'facets' => array(), 'fields' => array())) { //-- $connect = $this->solr_connect(); //-- if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') { //-- SmartFrameworkRegistry::setDebugMsg('db', 'solr|total-queries', 1, '+'); //-- $time_start = microtime(true); //-- } //end if //-- $query = new SolrQuery(); $query->setQuery(SolrUtils::escapeQueryChars("'" . $y_query) . "'"); if (Smart::array_size($y_options['settings']) > 0) { foreach ($y_options['settings'] as $key => $val) { $method = ucfirst(strtolower($key)); $query->{'set' . $method}($val); } //end for } //end if if (Smart::array_size($y_options['sort']) > 0) { foreach ($y_options['sort'] as $key => $val) { //echo 'Sort by: '.$key.' / '.$val.'<br>'; $query->addSortField($key, $val); } //end for } //end if if (Smart::array_size($y_options['filters']) > 0) { foreach ($y_options['filters'] as $key => $val) { //echo 'Filter Query: '.$key.' / '.$val.'<br>'; $query->addFilterQuery($key . ':"' . SolrUtils::escapeQueryChars($val) . '"'); } //end for } //end if $have_facets = false; if (Smart::array_size($y_options['facets']) > 0) { $have_facets = true; $query->setFacet(true); $query->setFacetMinCount(1); for ($i = 0; $i < Smart::array_size($y_options['facets']); $i++) { $query->addFacetField((string) $y_options['facets'][$i]); } //end for } //end if if (Smart::array_size($y_options['fields']) > 0) { for ($i = 0; $i < Smart::array_size($y_options['fields']); $i++) { $query->addField((string) $y_options['fields'][$i]); } //end for } //end if try { //-- $response = $this->instance->query($query); //-- } catch (Exception $e) { //-- Smart::log_warning('Solr ERROR # Query # EXCEPTION: ' . $e->getMessage() . "\n" . 'Query=' . print_r($query, 1)); return array(); // not connected //-- } //end try catch $response->setParseMode(SolrResponse::PARSE_SOLR_DOC); $data = $response->getResponse(); //print_r($data); //-- if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') { //-- $time_end = (double) (microtime(true) - (double) $time_start); //-- SmartFrameworkRegistry::setDebugMsg('db', 'solr|total-time', $time_end, '+'); //-- SmartFrameworkRegistry::setDebugMsg('db', 'solr|log', ['type' => 'nosql', 'data' => 'FIND-QUERY: ' . $y_query, 'command' => $y_options, 'time' => Smart::format_number_dec($time_end, 9, '.', '')]); //-- } //end if //-- if (!is_object($data)) { Smart::log_warning('Solr Query: Invalid Object Result'); return array(); // connection errors will be threated silently as Solr is a remote service } //end if if ($data instanceof SolrObject !== true) { Smart::log_warning('Solr Query: Invalid Object Instance Result'); return array(); // connection errors will be threated silently as Solr is a remote service } //end if //-- if (!is_object($data['responseHeader'])) { Smart::log_warning('Solr Query: Invalid Object ResponseHeader'); return array(); // connection errors will be threated silently as Solr is a remote service } //end if if ($data['responseHeader'] instanceof SolrObject !== true) { Smart::log_warning('Solr Query: Invalid Object Instance ResponseHeader'); return array(); // connection errors will be threated silently as Solr is a remote service } //end if //-- if ((string) $data['responseHeader']->status != '0') { Smart::log_warning('Solr Query: Invalid Status Result'); return array(); // connection errors will be threated silently as Solr is a remote service } //end if //-- if (!is_object($data['response'])) { Smart::log_warning('Solr Query: Invalid Object Response'); return array(); // connection errors will be threated silently as Solr is a remote service } //end if if ($data['response'] instanceof SolrObject !== true) { Smart::log_warning('Solr Query: Invalid Object Instance Response'); return array(); // connection errors will be threated silently as Solr is a remote service } //end if //-- if (!is_array($data['response']->docs)) { $this->error('Solr Query', 'Invalid Response Document Format', $y_query); return array(); } //end if //-- if ($have_facets and is_object($data['facet_counts'])) { return array('header' => $data['responseHeader'], 'total' => (int) $data['response']->numFound, 'docs' => (array) $data['response']->docs, 'facets' => (array) $data['facet_counts']->facet_fields); } else { return array('header' => $data['responseHeader'], 'total' => (int) $data['response']->numFound, 'docs' => (array) $data['response']->docs); } //end if else //-- }
<?php include "bootstrap.php"; $response = file_get_contents(DOCUMENT_RESPONSE_XML_2); $object = SolrUtils::digestXmlResponse($response); $dotted_property = $object["dotted.property"]; print_r($dotted_property);
/** * Escape a string and remove solr special characters * @param string $string the string to escape * @return string the escaped string */ public function escape($string) { return SolrUtils::escapeQueryChars($string); }
/** * Execute a search. * * @param string $query The XQuery script in binary encoding. * @param string $handler The Query Handler to use (null for default) * @param array $filter The fields and values to filter results on * @param int $start The record to start with * @param int $limit The amount of records to return * @param array $facet An array of faceting options * @param string $spell Phrase to spell check * @param string $dictionary Spell check dictionary to use * @param string $sort Field name to use for sorting * @param string $fields A list of fields to be returned * @param string $method Method to use for sending request (GET/POST) * @param bool $returnSolrError If Solr reports a syntax error, * should we fail outright (false) or * treat it as an empty result set with * an error key set (true)? * @access public * @throws object PEAR Error * @return array An array of query results */ function search($query, $handler = null, $filter = null, $start = 0, $limit = 20, $facet = null, $spell = '', $dictionary = null, $sort = null, $fields = null, $method = HTTP_REQUEST_METHOD_POST, $returnSolrError = false) { global $timer; // Query String Parameters $options = array('q' => $query, 'rows' => $limit, 'start' => $start, 'indent' => 'yes'); //For FRBR, enable this and then update display //$options['group'] = 'true'; //$options['group.field'] = 'grouping_term'; // Add Sorting if ($sort && !empty($sort)) { // There may be multiple sort options (ranked, with tie-breakers); // process each individually, then assemble them back together again: $sortParts = explode(',', $sort); for ($x = 0; $x < count($sortParts); $x++) { $sortParts[$x] = $this->_normalizeSort($sortParts[$x]); } $options['sort'] = implode(',', $sortParts); } //Check to see if we need to automatically convert to a proper case only (no stemming search) //We will do this whenever all or part of a string is surrounded by quotes. if (preg_match('/\\".+?\\"/', $query)) { if ($handler == 'Keyword') { $handler = 'KeywordProper'; } else { if ($handler == 'Subject') { $handler = 'SubjectProper'; } else { if ($handler == 'AllFields') { $handler = 'AllFieldsProper'; } else { if ($handler == 'Title') { $handler = 'TitleProper'; } } } } } // Determine which handler to use if (!$this->isAdvanced($query)) { //Escape : to make sure that the query isn't treated as a field spec. $query = str_replace(':', '\\:', $query); $ss = is_null($handler) ? null : $this->_getSearchSpecs($handler); // Is this a Dismax search? if (isset($ss['DismaxFields'])) { // Specify the fields to do a Dismax search on: $options['qf'] = implode(' ', $ss['DismaxFields']); // Specify the default dismax search handler so we can use any // global settings defined by the user: $options['qt'] = 'dismax'; // Load any custom Dismax parameters from the YAML search spec file: if (isset($ss['DismaxParams']) && is_array($ss['DismaxParams'])) { foreach ($ss['DismaxParams'] as $current) { $options[$current[0]] = $current[1]; } } // Apply search-specific filters if necessary: if (isset($ss['FilterQuery'])) { if (is_array($filter)) { $filter[] = $ss['FilterQuery']; } else { $filter = array($ss['FilterQuery']); } } } else { // Not DisMax... but do we need to format the query based on // a setting in the YAML search specs? If $ss is an array // at this point, it indicates that we found YAML details. if (is_array($ss)) { $options['q'] = $this->_buildQueryComponent($handler, $query); } else { if (!empty($handler)) { $options['q'] = "({$handler}:{$query})"; } } } } else { // Force boolean operators to uppercase if we are in a case-insensitive // mode: if (!$this->caseSensitiveBooleans) { $query = SolrUtils::capitalizeBooleans($query); } // Process advanced search -- if a handler was specified, let's see // if we can adapt the search to work with the appropriate fields. if (!empty($handler)) { $options['q'] = $this->_buildAdvancedQuery($handler, $query); } } $timer->logTime("build query"); // Limit Fields if ($fields) { $options['fl'] = $fields; } else { // This should be an explicit list $options['fl'] = '*,score'; } if (is_object($this->searchSource)) { $defaultFilters = preg_split('/\\r\\n/', $this->searchSource->defaultFilter); foreach ($defaultFilters as $tmpFilter) { $filter[] = $tmpFilter; } } //Apply automatic boosting (only to biblio and econtent queries) if (preg_match('/.*(biblio|econtent).*/i', $this->host)) { //unset($options['qt']); //Force the query to never use dismax handling $searchLibrary = Library::getSearchLibrary($this->searchSource); //Boost items owned at our location $searchLocation = Location::getSearchLocation($this->searchSource); $boostFactors = $this->getBoostFactors($searchLibrary, $searchLocation); if (isset($options['qt']) && $options['qt'] == 'dismax') { //Boost by number of holdings if (count($boostFactors) > 0) { $options['bf'] = "sum(" . implode(',', $boostFactors) . ")"; } //print ($options['bq']); } else { $baseQuery = $options['q']; //Boost items in our system if (count($boostFactors) > 0) { $boost = "sum(" . implode(',', $boostFactors) . ")"; } else { $boost = ''; } $options['q'] = "{!boost b={$boost}} {$baseQuery}"; //echo ("Advanced Query " . $options['q']); } $timer->logTime("apply boosting"); $scopingFilters = $this->getScopingFilters($searchLibrary, $searchLocation); $timer->logTime("apply filters based on location"); } else { //Non book search (genealogy) $scopingFilters = array(); } if ($filter != null && $scopingFilters != null) { if (!is_array($filter)) { $filter = array($filter); } $filters = array_merge($filter, $scopingFilters); } else { if ($filter == null) { $filters = $scopingFilters; } else { $filters = $filter; } } // Build Facet Options if ($facet && !empty($facet['field'])) { $options['facet'] = 'true'; $options['facet.mincount'] = 1; $options['facet.limit'] = isset($facet['limit']) ? $facet['limit'] : null; unset($facet['limit']); if (isset($facet['field']) && is_array($facet['field']) && in_array('date_added', $facet['field'])) { $options['facet.date'] = 'date_added'; $options['facet.date.end'] = 'NOW'; $options['facet.date.start'] = 'NOW-1YEAR'; $options['facet.date.gap'] = '+1WEEK'; foreach ($facet['field'] as $key => $value) { if ($value == 'date_added') { unset($facet['field'][$key]); break; } } } if (isset($facet['field'])) { $options['facet.field'] = $facet['field']; if ($options['facet.field'] && is_array($options['facet.field'])) { foreach ($options['facet.field'] as $key => $facetName) { if (strpos($facetName, 'availability_toggle') === 0) { $options['facet.field'][$key] = '{!ex=avail}' . $facetName; } } } } else { $options['facet.field'] = null; } unset($facet['field']); $options['facet.prefix'] = isset($facet['prefix']) ? $facet['prefix'] : null; unset($facet['prefix']); $options['facet.sort'] = isset($facet['sort']) ? $facet['sort'] : null; unset($facet['sort']); if (isset($facet['offset'])) { $options['facet.offset'] = $facet['offset']; unset($facet['offset']); } if ($searchLibrary && $searchLibrary->showAvailableAtAnyLocation) { $options['f.available_at.facet.missing'] = 'true'; } foreach ($facet as $param => $value) { $options[$param] = $value; } } $timer->logTime("build facet options"); //Check to see if there are filters we want to show all values for if (isset($filters) && is_array($filters)) { foreach ($filters as $key => $value) { if (strpos($value, 'availability_toggle') === 0) { $filters[$key] = '{!tag=avail}' . $value; } } } // Build Filter Query if (is_array($filters) && count($filters)) { $options['fq'] = $filters; } // Enable Spell Checking if ($spell != '') { $options['spellcheck'] = 'true'; $options['spellcheck.q'] = $spell; if ($dictionary != null) { $options['spellcheck.dictionary'] = $dictionary; } } // Enable highlighting if ($this->_highlight) { $options['hl'] = 'true'; $options['hl.fl'] = '*'; $options['hl.simple.pre'] = '{{{{START_HILITE}}}}'; $options['hl.simple.post'] = '{{{{END_HILITE}}}}'; } if ($this->debug) { echo '<pre>Search options: ' . print_r($options, true) . "\n"; if ($filters) { echo "\nFilterQuery: "; foreach ($filters as $filterItem) { echo " {$filterItem}"; } } if ($sort) { echo "\nSort: " . $options['sort']; } echo "</pre>\n"; $options['debugQuery'] = 'on'; } $timer->logTime("end solr setup"); $result = $this->_select($method, $options, $returnSolrError); $timer->logTime("run select"); if (PEAR_Singleton::isError($result)) { PEAR_Singleton::raiseError($result); } return $result; }
/** * Build Query string from search parameters * * @access private * @param array $search An array of search parameters * @return string The query */ private function buildQuery($search) { $groups = array(); $excludes = array(); if (is_array($search)) { $query = ''; foreach ($search as $params) { // Advanced Search if (isset($params['group'])) { $thisGroup = array(); // Process each search group foreach ($params['group'] as $group) { // Build this group individually as a basic search $thisGroup[] = $this->buildQuery(array($group)); } // Is this an exclusion (NOT) group or a normal group? if ($params['group'][0]['bool'] == 'NOT') { $excludes[] = join(" OR ", $thisGroup); } else { $groups[] = join(" " . $params['group'][0]['bool'] . " ", $thisGroup); } } // Basic Search if (isset($params['lookfor']) && $params['lookfor'] != '') { // Clean and validate input -- note that index may be in a different // field depending on whether this is a basic or advanced search. $lookfor = $params['lookfor']; if (isset($params['field'])) { $index = $params['field']; } else { if (isset($params['index'])) { $index = $params['index']; } else { $index = 'AllFields'; } } // Force boolean operators to uppercase if we are in a case-insensitive // mode: if (!$this->caseSensitiveBooleans) { $lookfor = SolrUtils::capitalizeBooleans($lookfor); } // Prepend the index name, unless it's the special "AllFields" index: if ($index != 'AllFields') { $query .= "{$index}:({$lookfor})"; } else { $query .= "{$lookfor}"; } } } } // Put our advanced search together if (count($groups) > 0) { $query = "(" . join(") " . $search[0]['join'] . " (", $groups) . ")"; } // and concatenate exclusion after that if (count($excludes) > 0) { $query .= " NOT ((" . join(") OR (", $excludes) . "))"; } // Ensure we have a valid query to this point return isset($query) ? $query : ''; }