diff --git a/search/engine/solr/classes/engine.php b/search/engine/solr/classes/engine.php index 1df982f1292aa0b88c648bdfa73457c415aea57c..8ca37e2def6cf22b4a9bfe6596c4989d2bedcf50 100644 --- a/search/engine/solr/classes/engine.php +++ b/search/engine/solr/classes/engine.php @@ -100,6 +100,13 @@ class engine extends \core_search\engine { */ protected $skippeddocs = 0; + /** + * Solr server major version. + * + * @var int + */ + protected $solrmajorversion = null; + /** * Initialises the search engine configuration. * @@ -889,6 +896,9 @@ class engine extends \core_search\engine { $url = $this->get_connection_url('/update/extract'); + // Return results as XML. + $url->param('wt', 'xml'); + // This will prevent solr from automatically making fields for every tika output. $url->param('uprefix', 'ignored_'); @@ -1122,12 +1132,18 @@ class engine extends \core_search\engine { * @return int */ public function get_solr_major_version() { + if ($this->solrmajorversion !== null) { + return $this->solrmajorversion; + } + // We should really ping first the server to see if the specified indexname is valid but // we want to minimise solr server requests as they are expensive. system() emits a warning // if it can not connect to the configured index in the configured server. $systemdata = @$this->get_search_client()->system(); $solrversion = $systemdata->getResponse()->offsetGet('lucene')->offsetGet('solr-spec-version'); - return intval(substr($solrversion, 0, strpos($solrversion, '.'))); + $this->solrmajorversion = intval(substr($solrversion, 0, strpos($solrversion, '.'))); + + return $this->solrmajorversion; } /** diff --git a/search/engine/solr/classes/schema.php b/search/engine/solr/classes/schema.php index f9e79cc001bbb659ab2158465e9941eb7f634e2f..86bd777ff2cf6e2412528e75e14d553b6c997618 100644 --- a/search/engine/solr/classes/schema.php +++ b/search/engine/solr/classes/schema.php @@ -86,8 +86,7 @@ class schema { */ public function can_setup_server() { - $engine = new \search_solr\engine(); - $status = $engine->is_server_configured(); + $status = $this->engine->is_server_configured(); if ($status !== true) { return $status; } @@ -95,7 +94,7 @@ class schema { // At this stage we know that the server is properly configured with a valid host:port and indexname. // We're not too concerned about repeating the SolrClient::system() call (already called in // is_server_configured) because this is just a setup script. - if ($engine->get_solr_major_version() < 5) { + if ($this->engine->get_solr_major_version() < 5) { // Schema setup script only available for 5.0 onwards. return get_string('schemasetupfromsolr5', 'search_solr'); } @@ -182,11 +181,13 @@ class schema { if (!isset($data['type']) || !isset($data['stored']) || !isset($data['indexed'])) { throw new \coding_exception($fieldname . ' does not define all required field params: type, stored and indexed.'); } + $type = $this->doc_field_to_solr_field($data['type']); + // Changing default multiValued value to false as we want to match values easily. $params = array( 'add-field' => array( 'name' => $fieldname, - 'type' => ($data['type'] === 'text' ? 'text_general' : $data['type']), + 'type' => $type, 'stored' => $data['stored'], 'multiValued' => false, 'indexed' => $data['indexed'] @@ -245,6 +246,7 @@ class schema { // All these field attributes are set when fields are added through this script and should // be returned and match the defined field's values. + $expectedsolrfield = $this->doc_field_to_solr_field($data['type']); if (empty($results->field) || !isset($results->field->type) || !isset($results->field->multiValued) || !isset($results->field->indexed) || !isset($results->field->stored)) { @@ -252,14 +254,13 @@ class schema { throw new \moodle_exception('errorcreatingschema', 'search_solr', '', get_string('schemafieldautocreated', 'search_solr', $fieldname)); - } else if (($results->field->type !== $data['type'] && - ($data['type'] !== 'text' || $results->field->type !== 'text_general')) || - $results->field->multiValued !== false || - $results->field->indexed !== $data['indexed'] || - $results->field->stored !== $data['stored']) { + } else if ($results->field->type !== $expectedsolrfield || + $results->field->multiValued !== false || + $results->field->indexed !== $data['indexed'] || + $results->field->stored !== $data['stored']) { - throw new \moodle_exception('errorcreatingschema', 'search_solr', '', - get_string('schemafieldautocreated', 'search_solr', $fieldname)); + throw new \moodle_exception('errorcreatingschema', 'search_solr', '', + get_string('schemafieldautocreated', 'search_solr', $fieldname)); } else { // The field already exists and it is properly defined, no need to create it. unset($fields[$fieldname]); @@ -309,4 +310,34 @@ class schema { } } + + /** + * Returns the solr field type from the document field type string. + * + * @param string $datatype + * @return string + */ + private function doc_field_to_solr_field($datatype) { + $type = $datatype; + + $solrversion = $this->engine->get_solr_major_version(); + + switch($datatype) { + case 'text': + $type = 'text_general'; + break; + case 'int': + if ($solrversion >= 7) { + $type = 'pint'; + } + break; + case 'tdate': + if ($solrversion >= 7) { + $type = 'pdate'; + } + break; + } + + return $type; + } } diff --git a/search/engine/solr/version.php b/search/engine/solr/version.php index 2bc7457a8f4463c0ae8dfe6a7b2bd145ab088792..6f4658f110a7542822b148645bf57244e6c8ff74 100644 --- a/search/engine/solr/version.php +++ b/search/engine/solr/version.php @@ -24,6 +24,6 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2017111300; +$plugin->version = 2017111700; $plugin->requires = 2017110800; $plugin->component = 'search_solr';