Duplicate nodes when using Views relationships

Created on 2 February 2018, almost 7 years ago
Updated 5 June 2024, 7 months ago

I have a view pulling in nodes that have multiple paragraphs referenced to them.
This works well and each node displays once in a table layout with the multiple paragraph fields displaying in each cell.
I currently have an exposed filter for searching some of the nodes fields.

The problem:

I would like to add an exposed filter to search the taxonomy in the paragraphs on the nodes.
In order to do that I need to add a relationship to the paragraph.
As soon as I add the relationship, the nodes repeat in the view for every paragraph associated with them.
If the node has 2 paragraphs referenced then the node shows 2 times. If I associate 3 paragraphs then the node shows 3 times.

Is this a glitch? How can I expose the paragraph filter and keep the nodes singular? I don't even need the paragraphs to be in the view. I just need to search for what paragraph data is in a node.

Am I missing something? I tried using distinct but can't get the distinct to work on the paragraph id nor the nid.

To reproduce:

Create a paragraph type with one or two fields.
Add an Entity reference of that paragraph to a node type. Make it the allowed values "unlimited".
Create a couple of nodes, one with two paragraphs referenced and another with one paragraph referenced.
Create a page view of these nodes. Only 2 nodes should show.
(In order to expose a filter with those paragraph fields, you need to add a "relationship".)
Add this paragraph as a relationship. Now you should have duplicate nodes showing. probably 3.

Tried Solutions:
distinct
aggregation
If I take the sql and run it through phpmyadmin, I can remove the paragraph field from the selection part of the query but leave the join aspect and it will display the right query still but I can't pull the paragraph field from the select in the views build.
Creates duplicates.

SELECT node__field_dtna_number.delta AS node__field_dtna_number_delta, node__field_dtna_number.langcode AS node__field_dtna_number_langcode, node__field_dtna_number.bundle AS node__field_dtna_number_bundle, node__field_dtna_number.field_dtna_number_value AS node__field_dtna_number_field_dtna_number_value, node_field_data.nid AS nid, file_managed_node__field_drawing_file.fid AS file_managed_node__field_drawing_file_fid, paragraphs_item_field_data_node__field_application_relation.id AS paragraphs_item_field_data_node__field_application_relation_
FROM 
{node_field_data} node_field_data
LEFT JOIN {node__field_drawing_file} node__field_drawing_file ON node_field_data.nid = node__field_drawing_file.entity_id AND node__field_drawing_file.deleted = '0' AND (node__field_drawing_file.langcode = node_field_data.langcode OR node__field_drawing_file.bundle = 'cac')
LEFT JOIN {file_managed} file_managed_node__field_drawing_file ON node__field_drawing_file.field_drawing_file_target_id = file_managed_node__field_drawing_file.fid
LEFT JOIN {node__field_application_relation} node__field_application_relation ON node_field_data.nid = node__field_application_relation.entity_id AND node__field_application_relation.deleted = '0' AND (node__field_application_relation.langcode = node_field_data.langcode OR node__field_application_relation.bundle = 'cac')
LEFT JOIN {paragraphs_item_field_data} paragraphs_item_field_data_node__field_application_relation ON node__field_application_relation.field_application_relation_target_revision_id = paragraphs_item_field_data_node__field_application_relation.revision_id
LEFT JOIN {node__field_dtna_number} node__field_dtna_number ON node_field_data.nid = node__field_dtna_number.entity_id AND node__field_dtna_number.deleted = '0' AND (node__field_dtna_number.langcode = node_field_data.langcode OR node__field_dtna_number.bundle = 'cac')
LEFT JOIN {node__field_searchable_oe} node__field_searchable_oe ON node_field_data.nid = node__field_searchable_oe.entity_id AND node__field_searchable_oe.deleted = '0' AND (node__field_searchable_oe.langcode = node_field_data.langcode OR node__field_searchable_oe.bundle = 'cac')
LEFT JOIN {node__field_searchable_prefixes} node__field_searchable_prefixes ON node_field_data.nid = node__field_searchable_prefixes.entity_id AND node__field_searchable_prefixes.deleted = '0' AND (node__field_searchable_prefixes.langcode = node_field_data.langcode OR node__field_searchable_prefixes.bundle = 'cac')
LEFT JOIN {node__field_duralite_prefix_numbers} node__field_duralite_prefix_numbers ON node_field_data.nid = node__field_duralite_prefix_numbers.entity_id AND node__field_duralite_prefix_numbers.deleted = '0'
WHERE (node_field_data.status = '1') AND (node_field_data.type IN ('cac')) AND (node_field_data.title IS NOT NULL) AND ((CONCAT_WS(' ', node__field_searchable_oe.field_searchable_oe_value, ' ', node__field_searchable_prefixes.field_searchable_prefixes_value, ' ', node__field_duralite_prefix_numbers.field_duralite_prefix_numbers_value, ' ', node__field_dtna_number.field_dtna_number_value) LIKE '%FRDAC-5Q%'))
LIMIT 20 OFFSET 0

Does not create duplicates:
(removed "paragraphs_item_field_data_node__field_application_relation.id AS paragraphs_item_field_data_node__field_application_relation_")

SELECT node__field_dtna_number.delta AS node__field_dtna_number_delta, node__field_dtna_number.langcode AS node__field_dtna_number_langcode, node__field_dtna_number.bundle AS node__field_dtna_number_bundle, node__field_dtna_number.field_dtna_number_value AS node__field_dtna_number_field_dtna_number_value, node_field_data.nid AS nid, file_managed_node__field_drawing_file.fid AS file_managed_node__field_drawing_file_fid
FROM 
{node_field_data} node_field_data
LEFT JOIN {node__field_drawing_file} node__field_drawing_file ON node_field_data.nid = node__field_drawing_file.entity_id AND node__field_drawing_file.deleted = '0' AND (node__field_drawing_file.langcode = node_field_data.langcode OR node__field_drawing_file.bundle = 'cac')
LEFT JOIN {file_managed} file_managed_node__field_drawing_file ON node__field_drawing_file.field_drawing_file_target_id = file_managed_node__field_drawing_file.fid
LEFT JOIN {node__field_application_relation} node__field_application_relation ON node_field_data.nid = node__field_application_relation.entity_id AND node__field_application_relation.deleted = '0' AND (node__field_application_relation.langcode = node_field_data.langcode OR node__field_application_relation.bundle = 'cac')
LEFT JOIN {paragraphs_item_field_data} paragraphs_item_field_data_node__field_application_relation ON node__field_application_relation.field_application_relation_target_revision_id = paragraphs_item_field_data_node__field_application_relation.revision_id
LEFT JOIN {node__field_dtna_number} node__field_dtna_number ON node_field_data.nid = node__field_dtna_number.entity_id AND node__field_dtna_number.deleted = '0' AND (node__field_dtna_number.langcode = node_field_data.langcode OR node__field_dtna_number.bundle = 'cac')
LEFT JOIN {node__field_searchable_oe} node__field_searchable_oe ON node_field_data.nid = node__field_searchable_oe.entity_id AND node__field_searchable_oe.deleted = '0' AND (node__field_searchable_oe.langcode = node_field_data.langcode OR node__field_searchable_oe.bundle = 'cac')
LEFT JOIN {node__field_searchable_prefixes} node__field_searchable_prefixes ON node_field_data.nid = node__field_searchable_prefixes.entity_id AND node__field_searchable_prefixes.deleted = '0' AND (node__field_searchable_prefixes.langcode = node_field_data.langcode OR node__field_searchable_prefixes.bundle = 'cac')
LEFT JOIN {node__field_duralite_prefix_numbers} node__field_duralite_prefix_numbers ON node_field_data.nid = node__field_duralite_prefix_numbers.entity_id AND node__field_duralite_prefix_numbers.deleted = '0'
WHERE (node_field_data.status = '1') AND (node_field_data.type IN ('cac')) AND (node_field_data.title IS NOT NULL) AND ((CONCAT_WS(' ', node__field_searchable_oe.field_searchable_oe_value, ' ', node__field_searchable_prefixes.field_searchable_prefixes_value, ' ', node__field_duralite_prefix_numbers.field_duralite_prefix_numbers_value, ' ', node__field_dtna_number.field_dtna_number_value) LIKE '%FRDAC-5Q%'))
LIMIT 20 OFFSET 0
🐛 Bug report
Status

Closed: duplicate

Version

1.0

Component

Miscellaneous

Created by

🇨🇦Canada strawman

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇮🇳India rameshbalda

    function your_module_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
    if ($view->id() == 'myviewid' && $view->getDisplay()->display['id'] == 'block_1' ) {
    $query->addField('', 'nid', '', ['function' => 'groupby']);
    $query->addGroupBy('nid');
    }
    }

  • 🇸🇰Slovakia lubwn

    I have a very big query with lots of sorting and exposed fields so I was not comfortable with adding custom query to this, potentionally breaking things.

    I came up with elegant solution without coding. You basicly only need to know which multi-valued field is creating the duplicates. Often it is some taxonomy or entity reference or reference to image field or so, and then you just add filter with DELTA lower than 1. This will eventually filter-out the duplicates completely. No aggregation or coding needed.

  • 🇮🇹Italy itamair

    Agree with @lubwn ... usually properly limiting with Deltas the presence of Multivalue fields (also from relationships) and DISTINCT query option solves the duplications.

  • 🇲🇽Mexico preciado04 Tepic

    Comment #13 🐛 Duplicate nodes when using Views relationships Closed: duplicate worked for me.

    The only detail is, I had to modify a little bit the query.

    use Drupal\views\ViewExecutable;
    use Drupal\views\Plugin\views\query\QueryPluginBase;
    
    /**
     * Implements hook_views_query_alter().
     */
    function mymodule_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
      switch($view->storage->id()){
        case 'my_view_id';
          $query->addField('node', 'nid', '', ['function' => 'groupby']);
          $query->addGroupBy('node.nid');
          break;
      }
    }
    
  • 🇧🇪Belgium Vacilando Brussels

    #24 (based on #18) works perfectly, thanks!

    Is there in the meantime a module that solves this problem in a generic way for views with this kind of relationships?

  • 🇺🇸United States attheshow

    #53 is working well for me.

  • #51 set me on the right track. I had a view with a relationship to another entity with multiple cardinality. Each additional reference was causing a another row for the exact same entity. By setting a filter on the delta and only showing those with delta = 0, it limited the results to one per actual entity, despite having multiple references to another entity.

    I tried to implement hook_views_query_alter() but I kept getting weird results with ViewsBulkOperations so I opted for the filter against the delta instead.

  • 🇮🇳India bhupendra_kanojiya

    @perfectcu.be thanks, #41 works for me.

  • 🇺🇸United States LDenise

    #13 works for me too. Thanks for the tip!

  • 🇮🇹Italy em-it Lombardy

    IMHO, once one's understood the underlaying mechanisms #18 is the best solution! It is clean and effective.

    I had a similar issue: trying to list custom entities, which reference multiple values from three taxonomies (i.e., each entity has 3 separate fields, and each field is set with Allowed number of values > 1 - or unlimited).
    I wanted to show those linked taxonomies, as well as filtering by their label values (not simply their term-ids). Thus I had add relationships to each taxonomy... ending in i x j x k rows per each entity record - where i, j and k are the number of taxonomy terms referenced by that record (sometimes, 3 x 2 x 2, resulting in 12 rows for a single entity!).

    Setting Use aggregation (in Advanced > Other) to Yes, then adjusting Group column to Entity ID in Aggregation settings for each involved field (i.e., only the fields taken from those multi-referenced taxonomy terms, no need to set this for all fields of my view) was enough to finally reduce each record to a single row.
    By the way, no need to set Distinct on within the Query settings.

    @hodba Thanks a lot!

Production build 0.71.5 2024