コード例 #1
0
 /**
  * Test capitalizeRanges functionality.
  *
  * @return void
  * @access public
  */
 public function testCapitalizeRanges()
 {
     // Set up an array of expected inputs and outputs:
     // @codingStandardsIgnoreStart
     $tests = array(array('"{a to b}"', '"{a to b}"'), array('"[a to b]"', '"[a to b]"'), array('[a to b]', '([a TO b] OR [A TO B])'), array('[a TO b]', '([a TO b] OR [A TO B])'), array('[a To b]', '([a TO b] OR [A TO B])'), array('[a tO b]', '([a TO b] OR [A TO B])'), array('{a to b}', '({a TO b} OR {A TO B})'), array('{a TO b}', '({a TO b} OR {A TO B})'), array('{a To b}', '({a TO b} OR {A TO B})'), array('{a tO b}', '({a TO b} OR {A TO B})'), array('[1900 to 1910]', '[1900 TO 1910]'), array('[1900 TO 1910]', '[1900 TO 1910]'), array('{1900 to 1910}', '{1900 TO 1910}'), array('{1900 TO 1910}', '{1900 TO 1910}'), array('[a      to      b]', '([a TO b] OR [A TO B])'), array('[1900-01-01t00:00:00z to 1900-12-31t23:59:59z]', '[1900-01-01T00:00:00Z TO 1900-12-31T23:59:59Z]'), array('{1900-01-01T00:00:00Z       TO   1900-12-31T23:59:59Z}', '{1900-01-01T00:00:00Z TO 1900-12-31T23:59:59Z}'));
     // @codingStandardsIgnoreEnd
     // Test all the operations:
     foreach ($tests as $current) {
         $this->assertEquals(VuFindSolrUtils::capitalizeRanges($current[0]), $current[1]);
     }
 }
コード例 #2
0
ファイル: Solr.php プロジェクト: bharatm/NDL-VuFind
 /**
  * Execute a search.
  *
  * @param string $query           The search query
  * @param string $handler         The Query Handler to use (null for default)
  * @param array  $filter          The fields and values to filter results on
  * @param string $start           The record to start with
  * @param string $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 Fail outright on syntax error (false) or
  * treat it as an empty result set with an error key set (true)?
  *
  * @throws object                 PEAR Error
  * @return array                  An array of query results
  * @access public
  */
 public 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)
 {
     // Query String Parameters
     $options = array('q' => $query, 'rows' => $limit, 'start' => $start, 'indent' => 'yes');
     // Force sort by title_sort for empty search sorted by score
     if ($limit > 0 && $query == '*:*' && (empty($sort) || $sort == 'score desc')) {
         $sort = 'title asc';
     }
     // 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);
     }
     // Determine which handler to use
     if (!$this->isAdvanced($query)) {
         $ss = is_null($handler) ? null : $this->_getSearchSpecs($handler, $query);
         // 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) {
                     // The way we process the current parameter depends on
                     // whether or not we have previously encountered it.  If
                     // we have multiple values for the same parameter, we need
                     // to turn its entry in the $options array into a subarray;
                     // otherwise, one-off parameters can be safely represented
                     // as single values.
                     if (isset($options[$current[0]])) {
                         if (!is_array($options[$current[0]])) {
                             $options[$current[0]] = array($options[$current[0]]);
                         }
                         $options[$current[0]][] = $current[1];
                     } else {
                         $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 if we have a handler set, we may still need
             // to build a query using a setting in the YAML search specs or a
             // simple field name:
             if (!empty($handler)) {
                 $options['q'] = $this->_buildQueryComponent($handler, $query);
             }
         }
     } else {
         // Force boolean operators to uppercase if we are in a case-insensitive
         // mode:
         if (!$this->_caseSensitiveBooleans) {
             $query = VuFindSolrUtils::capitalizeBooleans($query);
         }
         // Adjust range operators if we are in a case-insensitive mode:
         if (!$this->_caseSensitiveRanges) {
             $query = VuFindSolrUtils::capitalizeRanges($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);
             // If highlighting is enabled, we only want to use the inner query
             // for highlighting; anything added outside of this is a boost and
             // should be ignored for highlighting purposes!
             if ($this->_highlight) {
                 $options['hl.q'] = $this->_buildAdvancedInnerQuery($handler, $query);
             }
         }
     }
     // Limit Fields
     if ($fields) {
         $options['fl'] = $fields;
     } else {
         // This should be an explicit list
         $options['fl'] = '*,score';
     }
     // 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']);
         $options['facet.field'] = isset($facet['field']) ? $facet['field'] : null;
         unset($facet['field']);
         if (isset($facet['prefix'])) {
             if (is_array($facet['prefix'])) {
                 foreach ($facet['prefix'] as $name => $prefix) {
                     $options["f.{$name}.facet.prefix"] = $prefix;
                     // TODO: This is a kludge, maybe something better is
                     // needed to indicate when we want more than the default
                     // limit for hierarchical facets.
                     $options["f.{$name}.facet.limit"] = 1000;
                 }
             } else {
                 $options['facet.prefix'] = $facet['prefix'];
             }
         }
         unset($facet['prefix']);
         $options['facet.sort'] = isset($facet['sort']) ? $facet['sort'] : 'count';
         unset($facet['sort']);
         if (isset($facet['offset'])) {
             $options['facet.offset'] = $facet['offset'];
             unset($facet['offset']);
         }
         if (isset($facet['query'])) {
             $options['facet.query'] = $facet['query'];
             unset($facet['query']);
         }
         foreach ($facet as $param => $value) {
             $options[$param] = $value;
         }
     }
     // Don't use the filters for an id query
     if ($handler != 'ids') {
         if ($this->_mergedRecords) {
             // Filter out merged children by default
             if (!isset($filter)) {
                 $filter = array();
             }
             $filter[] = '-merged_child_boolean:TRUE';
         } elseif ($this->_mergedRecords !== null) {
             // Filter out merged records by default
             if (!isset($filter)) {
                 $filter = array();
             }
             $filter[] = '-merged_boolean:TRUE';
         }
         if ($this->_hideComponentParts) {
             // Filter out component parts by default
             if (!isset($filter)) {
                 $filter = array();
             }
             $filter[] = '-hidden_component_boolean:TRUE';
         }
     }
     // Build Filter Query
     $this->_mergeBuildingPriority = array();
     if (is_array($filter) && count($filter)) {
         // Change 'online_boolean' filter to 'online_str_mv'
         // if sources contain merged records (i.e. if deduplication is enabled).
         if (($pos = array_search('online_boolean:"1"', $filter)) !== false) {
             $searchSettings = getExtraConfigArray('searches');
             if (isset($searchSettings['Records']['merged_records']) && $searchSettings['Records']['merged_records']) {
                 if (isset($searchSettings['Records']['sources']) && ($sources = $searchSettings['Records']['sources']) !== '') {
                     $tmp = array();
                     foreach (explode(',', $sources) as $source) {
                         $tmp[] = "\"{$source}\"";
                     }
                     $filter[$pos] = 'online_str_mv:(' . implode(' OR ', $tmp) . ')';
                 } else {
                     $filter[$pos] = 'online_str_mv:*';
                 }
             }
         }
         $options['fq'] = $filter;
         foreach ($filter as $f) {
             if (strncmp($f, 'building:', 9) == 0) {
                 // Assume we have a facet hierarchy...
                 $fullHierarchy = substr($f, 12, -1);
                 foreach (explode('/', $fullHierarchy) as $part) {
                     $this->_mergeBuildingPriority[] = $part;
                 }
             }
         }
     }
     // 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}}}}';
     }
     // Hack to make it possible to see the search debug information
     if (isset($_REQUEST['debugSolrQuery'])) {
         $options['debugQuery'] = 'true';
     }
     if ($this->debug) {
         echo '<pre>Search options: ' . print_r($options, true) . "\n";
         if ($filter) {
             echo "\nFilterQuery: ";
             foreach ($filter as $filterItem) {
                 echo " {$filterItem}";
             }
         }
         if ($sort) {
             echo "\nSort: " . $options['sort'];
         }
         echo "</pre>\n";
     }
     $result = $this->_select($method, $options, $returnSolrError);
     if (PEAR::isError($result)) {
         PEAR::raiseError($result);
     }
     return $result;
 }