Skip to content

Commit

Permalink
MDL-60759 search_solr: Solr 7+ compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
David Monllao committed Dec 11, 2017
1 parent 109aa07 commit 895e005
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 13 deletions.
18 changes: 17 additions & 1 deletion search/engine/solr/classes/engine.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -889,6 +896,9 @@ protected function add_stored_file($document, $storedfile) {

$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_');

Expand Down Expand Up @@ -1122,12 +1132,18 @@ public function is_server_configured() {
* @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;
}

/**
Expand Down
53 changes: 42 additions & 11 deletions search/engine/solr/classes/schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,15 @@ public function __construct() {
*/
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;
}

// 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');
}
Expand Down Expand Up @@ -182,11 +181,13 @@ protected function add_fields($fields, $checkexisting = true) {
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']
Expand Down Expand Up @@ -245,21 +246,21 @@ protected function validate_fields(&$fields, $requireexisting = false) {
// 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)) {

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]);
Expand Down Expand Up @@ -309,4 +310,34 @@ protected function validate_add_field_result($result) {
}

}

/**
* 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;
}
}
2 changes: 1 addition & 1 deletion search/engine/solr/version.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@

defined('MOODLE_INTERNAL') || die();

$plugin->version = 2017111300;
$plugin->version = 2017111700;
$plugin->requires = 2017110800;
$plugin->component = 'search_solr';

0 comments on commit 895e005

Please sign in to comment.