diff --git a/web/modules/custom/materio_sapi/src/Controller/Base.php b/web/modules/custom/materio_sapi/src/Controller/Base.php index 4de3e5a..541413b 100644 --- a/web/modules/custom/materio_sapi/src/Controller/Base.php +++ b/web/modules/custom/materio_sapi/src/Controller/Base.php @@ -27,21 +27,110 @@ class Base extends ControllerBase { // https://www.hashbangcode.com/article/drupal-8-date-search-boosting-search-api-and-solr-search // https://kgaut.net/blog/2018/drupal-8-search-api-effectuer-une-requete-dans-le-code.html + $lang = \Drupal::languageManager()->getCurrentLanguage()->getId(); + $this->index = Index::load('database'); - // // get solarium fileds name - // $solrFields = $this->index->getServerInstance() - // ->getBackend() - // ->getSolrFieldNames($this->index); - // - // // tag_tid"itm_tag_tid" - // // thesaurus_tid"itm_thesaurus_tid" - // $taxoSolrFieldsName = []; - // foreach (['tag_tid', 'thesaurus_tid'] as $f) { - // $taxoSolrFieldsName[] = $solrFields[$f]; - // } + $this->results = [ + 'uuids' => [], + 'nids' => [] + ]; - $this->query = $this->index->query(); + // AND QUERY + $this->and_query = $this->index->query(['offset'=>0,'limit'=>10000]); + // set parse mode and conjunction + $parse_mode = \Drupal::service('plugin.manager.search_api.parse_mode') + ->createInstance('terms'); + $parse_mode->setConjunction('AND'); + $this->and_query->setParseMode($parse_mode); + // Set fulltext search keywords and fields. + $this->and_query->keys($this->keys); + // $this->and_query->setFulltextFields(['field_reference']); + // in case we search for material references like W0117 + if (preg_match_all('/[WTRPCMFGSO]\d{4}/i', $this->keys, $matches)) { + $ref_conditions = $this->and_query->createConditionGroup('OR'); + foreach ($matches[0] as $key => $value) { + $ref_conditions->addCondition('field_reference', $value); + } + $this->and_query->addConditionGroup($ref_conditions); + } + // in case of term id provided restrict the keys to taxo fields + if ($this->term) { + $term_conditions = $this->and_query->createConditionGroup('OR'); + $term = (int) $this->term; + foreach (['tag_tid', 'thesaurus_tid'] as $field) { + $term_conditions->addCondition($field, $term); + } + $this->and_query->addConditionGroup($term_conditions); + + // INSTEAD TRY TO BOOST THE TAG AND THESAURUS FIELDS + // foreach ($taxoSolrFieldsName as $fname) { + // // $solarium_query->addParam('bf', "recip(abs(ms(NOW,{$solrField})),3.16e-11,10,0.1)"); + // $bfparam = "if(gt(termfreq({$fname},{$this->term}),0),^21,0)"; + // $this->or_query->addParam('bf', $bfparam); + // } + // look @ materio_sapi_search_api_solr_query_alter in materio_sapi.module + // $this->or_query->setOption('termid', $this->term); + } + // FILTERS + if ($this->filters) { + $filters_conditions = $this->and_query->createConditionGroup('AND'); + foreach ($this->filters as $filter) { + $filter = (int) $filter; + foreach (['tag_tid', 'thesaurus_tid'] as $field) { + $filters_conditions->addCondition($field, $filter); + } + } + $this->and_query->addConditionGroup($filters_conditions); + }else{ + // Recherche uniquement sur le champ « body » + $this->and_query->setFulltextFields([ + 'thesaurus_name_0', + 'thesaurus_synonyms_0', + 'thesaurus_name_1', + 'thesaurus_synonyms_1', + 'thesaurus_name_2', + 'thesaurus_synonyms_2', + 'thesaurus_name_3', + 'thesaurus_synonyms_3', + 'thesaurus_name_4', + 'thesaurus_synonyms_4', + 'thesaurus_name', + 'thesaurus_synonyms', + 'tag_name', + 'tag_synonyms' + ]); + } + + + + // Restrict the search to specific languages. + $this->and_query->setLanguages([$lang]); + + // Do paging. + // $this->and_query->range($this->offset, $this->limit); + // retrieve all results + // $this->and_query->range(0, -1); + + // Add sorting. + $this->and_query->sort('search_api_relevance', 'DESC'); + + // Set one or more tags for the query. + // @see hook_search_api_query_TAG_alter() + // @see hook_search_api_results_TAG_alter() + $this->and_query->addTag('materio_sapi_search_and_query'); + + $and_results = $this->and_query->execute(); + + foreach ($and_results as $result) { + $this->results['uuids'][] = $result->getField('uuid')->getValues()[0]; + $this->results['nids'][] = $result->getField('nid')->getValues()[0]; + } + + // + // OR QUERY + // + $this->or_query = $this->index->query(['offset'=>0,'limit'=>10000]); // Change the parse mode for the search. // Les différentes possibilités sont @@ -49,72 +138,44 @@ class Base extends ControllerBase { // - « terms » => Multiple words // - « phrase » => Single phrase // - " edismax " => ??? - $parse_mode = \Drupal::service('plugin.manager.search_api.parse_mode') + $or_parse_mode = \Drupal::service('plugin.manager.search_api.parse_mode') ->createInstance('direct'); - $parse_mode->setConjunction('OR'); - $this->query->setParseMode($parse_mode); + $or_parse_mode->setConjunction('OR'); + $this->or_query->setParseMode($or_parse_mode); // Set fulltext search keywords and fields. - $this->query->keys($this->keys); - // $this->query->setFulltextFields(['field_reference']); + $this->or_query->keys($this->keys); + // $this->or_query->setFulltextFields(['field_reference']); - // Set additional conditions. - // in case we search for material references like W0117 - if (preg_match_all('/[WTRPCMFGSO]\d{4}/i', $this->keys, $matches)) { - $ref_conditions = $this->query->createConditionGroup('OR'); - foreach ($matches[0] as $key => $value) { - $ref_conditions->addCondition('field_reference', $value); - } - $this->query->addConditionGroup($ref_conditions); - } - // in case of term id provided restrict the keys to taxo fields - if ($this->term) { - // $term_conditions = $this->query->createConditionGroup('OR'); - // $term = (int) $this->term; - // foreach (['tag_tid', 'thesaurus_tid'] as $field) { - // $term_conditions->addCondition($field, $term); - // } - // $this->query->addConditionGroup($term_conditions); - - // INSTEAD TRY TO BOOST TTHE TAG AND THESAURUS FIELDS - // foreach ($taxoSolrFieldsName as $fname) { - // // $solarium_query->addParam('bf', "recip(abs(ms(NOW,{$solrField})),3.16e-11,10,0.1)"); - // $bfparam = "if(gt(termfreq({$fname},{$this->term}),0),^21,0)"; - // $this->query->addParam('bf', $bfparam); - // } - - $this->query->setOption('termid', $this->term); - } - - // filter the search - if ($this->filters) { - $filters_conditions = $this->query->createConditionGroup('OR'); - foreach ($this->filters as $filter) { - $filter = (int) $filter; - foreach (['tag_tid', 'thesaurus_tid'] as $field) { - $filters_conditions->addCondition($field, $filter); - } - } - $this->query->addConditionGroup($filters_conditions); + // exclude results from and_query + $exclude_and_results_conditions = $this->or_query->createConditionGroup('AND'); + foreach ($this->results['nids'] as $nid) { + $exclude_and_results_conditions->addCondition('nid', $nid, '<>'); } + $this->or_query->addConditionGroup($exclude_and_results_conditions); // Restrict the search to specific languages. - $lang = \Drupal::languageManager()->getCurrentLanguage()->getId(); - $this->query->setLanguages([$lang]); + $this->or_query->setLanguages([$lang]); // Do paging. - $this->query->range($this->offset, $this->limit); + // $this->or_query->range($this->offset, $this->limit); + // retrieve all results + // $this->or_query->range(0, -1); // Add sorting. - $this->query->sort('search_api_relevance', 'DESC'); + $this->or_query->sort('search_api_relevance', 'DESC'); // Set one or more tags for the query. // @see hook_search_api_query_TAG_alter() // @see hook_search_api_results_TAG_alter() - $this->query->addTag('materio_sapi_search'); + $this->or_query->addTag('materio_sapi_search_or_query'); - $this->results = $this->query->execute(); + $or_results = $this->or_query->execute(); + foreach ($or_results as $result) { + $this->results['uuids'][] = $result->getField('uuid')->getValues()[0]; + $this->results['nids'][] = $result->getField('nid')->getValues()[0]; + } } private function defaultQuery(){ @@ -138,6 +199,7 @@ class Base extends ControllerBase { ->count(); $this->count = $this->count_query->execute(); } + /** * get params from request */ @@ -179,33 +241,24 @@ class Base extends ControllerBase { $resp['keys'] = $this->keys; $resp['term'] = $this->term; - $resp['count'] = $this->results->getResultCount(); + // $resp['count'] = $this->results->getResultCount(); + $resp['count'] = count($this->results['nids']); $resp['infos'] = t('The search found @count result(s) with keywords @keys.', array( "@count" => $resp['count'], "@keys" => $this->keys )); - $resp['options'] = $this->query->getOptions(); + // $resp['options'] = $this->query->getOptions(); - // $items = []; - $uuids = []; - $nids = []; - foreach ($this->results as $result) { - // $nid = $result->getField('nid')->getValues()[0]; - // $uuid = $result->getField('uuid')->getValues()[0]; - // $title = $result->getField('title')->getValues()[0]->getText(); - // $items[] = [ - // 'nid' => $nid, - // 'uuid' => $uuid, - // 'title' => $title, - // ]; - $uuids[] = $result->getField('uuid')->getValues()[0]; - $nids[] = $result->getField('nid')->getValues()[0]; - } - // $resp['items'] = $items; - $resp['uuids'] = $uuids; - $resp['nids'] = $nids; + // $uuids = []; + // $nids = []; + // foreach ($this->results as $result) { + // $uuids[] = $result->getField('uuid')->getValues()[0]; + // $nids[] = $result->getField('nid')->getValues()[0]; + // } + $resp['nids'] = array_slice($this->results['nids'], $this->offset, $this->limit); + $resp['uuids'] = array_slice($this->results['uuids'], $this->offset, $this->limit); } else { // no keys or terms to search for // display the default base page @@ -254,30 +307,34 @@ class Base extends ControllerBase { if ($this->keys) { $resp['#title'] = $this->keys; - $this->sapiQuery(); + // $this->sapiQuery(); - $node_view_builder = \Drupal::entityTypeManager()->getViewBuilder('node'); + // $node_storage = \Drupal::entityTypeManager()->getStorage('node'); + // $node_view_builder = \Drupal::entityTypeManager()->getViewBuilder('node'); - $items = $this->results->getResultItems(); - $this->items = []; - foreach ($items as $item) { - // \Drupal::logger('materio_sapi')->notice(print_r($item, true)); - try { - /** @var \Drupal\Core\Entity\EntityInterface $entity */ - $entity = $item->getOriginalObject()->getValue(); - } - catch (SearchApiException $e) { - continue; - } - if (!$entity) { - continue; - } - // TODO: define dynamicly viewmode - $this->items[] = $node_view_builder->view($entity, 'teaser'); + // // $items = $this->results->getResultItems(); + // $nids = $this->results['nids']; + // $this->items = []; + // foreach ($nids as $nid) { + // // \Drupal::logger('materio_sapi')->notice(print_r($nid, true)); + // try { + // /** @var \Drupal\Core\Entity\EntityInterface $entity */ + // // $entity = $item->getOriginalObject()->getValue(); + // $entity = $node_storage->load($nid); + // } + // catch (SearchApiException $e) { + // continue; + // } + // if (!$entity) { + // continue; + // } + // // TODO: define dynamicly viewmode + // $this->items[] = $node_view_builder->view($entity, 'teaser'); - } + // } - $resp['items'] = $this->items; + // $resp['items'] = $this->items; + $resp['items'] = []; }else{ $resp['#markup'] = t("no keys to search for"); }