0

I have an RSS feed display in a view, and one of the fields in the view is a multi-value taxonomy reference field. The feed settings have a "Grouping field" setting, and I've chosen that field (and I also have DISTINCT selected in the query settings), but I still get duplicate records.

When I run the query in MYSQL, I can see that it returns one record per term, so I'm guessing the grouping like that is handled in the display layer that an RSS view doesn't have (even though it does have a grouping setting).

That being said, what is a good place to filter out duplicate results? I saw the Views Distinct module, but it doesn't have a D8 release. In looking at the views hooks, it looks like hook_views_pre_render would be the best place, because at that point the query is run and the $view object has the results.

If anyone has experience with this or a better way, I'm open to suggestions.

Thanks.

1

Here's what I came up with that does the job:

/**
 * Implements hook_views_query_pre_render().
 */
function video_export_views_pre_render(Drupal\views\ViewExecutable $view) {
  $unique_nids = $new_results = array();

  // Loop through results and filter out duplicate results.
  foreach($view->result as $index => $result) {
    if(!in_array($result->nid, $unique_nids)) {
      $unique_nids[] = $result->nid;
    }
    else {
      $new_results[] = $result;
    }
  }
  // Replace $view->result with new array. Apparently views requires sequentially keyed
  // array of results instead of skipping keys (e.g. 0, 2, 4, etc), so we can't just
  // unset the duplicates.
  $view->result = $new_results;
}
  • The code in the else branch should go in the if statement; otherwise $result is added to $new_results when the node ID is already in the $unique_nids array. In other words, if there are 4 rows for the same node, the first row is not added to that array, but the other 3 rows are added. – kiamlaluno Mar 28 at 9:04
0

@wonder95, this doesn't seem to work for me since there are 2 errors in your code IMHO.

First, you should be filling up the $new_results array inside your if condition and not the else condition.

Secondly, $view->result = $new_results; has no affect on the final result set. You'll need to use unset instead.

Below is my final working code

function hook_views_pre_render(\Drupal\views\ViewExecutable $view) {
   if ($view->id() == 'my_view') {
     $unique_nids = array();
     foreach($view->result as $key => $result) {
       if(!in_array($result->nid, $unique_nids)) {
         $unique_nids[] = $result->nid;
       }
       else {
         unset($view->result[$key]);
       }
     }
   }
 }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.