Score:0

Programmatically remove duplicated nodes without changing the number of nodes shown per page

mr flag

I have a content type called Página de área (Area page) referenced by two content type: Article and Agrupador. I have a view that displays all the Article nodes that share at least one area with an Agrupador node.

My goal is removing the duplicate nodes (I get calling $query->addWhere()) from the view.
I already tried using the Distinct and Aggregation options in the user interface, but they didn't work for me. I'm aware that this can be achieved using hook_views_pre_render(), but if (for example) I have 10 nodes per page and two nodes are duplicates, the view ends up showing eight nodes instead of 10.

I also tried what shown in Update view result and pager in hook_views_pre_render() and in Distinct doesn't work when sorting by field with multiple values using the following code.

/**
 * Implements hook_views_query_alter().
 */
function gcaba_agrupador_views_query_alter(ViewExecutable $view, Sql $query) {
  if ($view->id() == 'noticias_agrupador' && $view->current_display == 'noticias_agrupador') {
    $agrupador = \Drupal::routeMatch()->getParameter('node');
    if ($agrupador instanceof NodeInterface) {
      $agrupador = Node::load($agrupador->id());
      $areas = explode(',', $agrupador->field_area->getString());
      $areasArray = array_map('intval', $areas);
      $query->addWhere(0, 'node__field_area.field_area_target_id', $areasArray, 'IN');
    }
  }  
}
apaderno avatar
us flag
What does *affecting the pager functionality* exactly mean? If a view is altered to show less nodes, the pager should be updated to still show the number of pages required to show all the nodes.
apaderno avatar
us flag
The question explains that `hook_views_pre_render()` would break the pager, but then shows an implementation of `hook_views_query_alter()` and it does not say what is wrong with that implementation.
apaderno avatar
us flag
(Those are probably the details missing in the question, for which the question has been voted to be closed.)
mx flag
You didn't include what Aggregation settings you tried. It can be be done with Aggregation but you have to know what you're doing, it doesn't happen by simply enabling it. You have to find which field should be changed to "Entity ID" from "Value" or something like that. You should also make that happen (remove duplicates) without any Sorting and maybe even Pagination, and only bring them back once you're able to aggregate duplicates into single rows.
Score:0
cn flag
use Drupal\views\ViewExecutable;
use Drupal\views\Plugin\views\query\QueryPluginBase;

/**
 * Implements hook_views_query_alter().
 *
 * @param \Drupal\views\ViewExecutable $view
 * @param \Drupal\views\Plugin\views\query\QueryPluginBase $query
 */
function gcaba_agrupador_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
  if ($view->id() == 'noticias_agrupador' && $view->current_display == 'noticias_agrupador') {
    $agrupador = \Drupal::routeMatch()->getParameter('node');
    if ($agrupador instanceof \Drupal\node\NodeInterface) {
      $agrupador = \Drupal\node\Entity\Node::load($agrupador->id());
      $areas = explode(',', $agrupador->field_area->getString());
      $areasArray = array_map('intval', $areas);
      
      $query->addWhere(0, 'node__field_area.field_area_target_id', $areasArray, 'IN');

      // Remove duplicates using DISTINCT.
      $query->distinct();
    }
  }
}

Jordi Bustos avatar
mr flag
Didn't work :( The pager is not updated with deleted nodes.
Rayan Frem avatar
cn flag
lets try a diffrent approach. I just updated the code by keeping the query alter and adding the distinct attribute. Try it and let me know
Jordi Bustos avatar
mr flag
It was a good shot. But distinct method is undefined
apaderno avatar
us flag
[`QueryPluginBase`](https://api.drupal.org/api/drupal/core%21modules%21views%21src%21Plugin%21views%21query%21QueryPluginBase.php/class/QueryPluginBase/9) shows all the available methods, but `distinct()` is not one of them.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.