Score:1

entityQuery returns wrong result: too many joins?

cn flag

I built an entityQuery for a custom entity type "vote". I only want to get those votes for a specific poll and those by deputies who are members of a specific fraction. The fraction membership can change over the time of the legislature so we have an additional custom entity of type "fraction_membership" in which the fraction and the time during which the fraction membership was valid can be set. So what we need is a query that gives just the votes of members of the fraction who were members of the fration at the time of the poll.

The valid time of a fraction_membership can be set in two date fields: valid_from and valid_until.

$fractionId = 22;
$pollId = 1234;
$pollDate = '2020-05-10'
$query = \Drupal::entityQuery('vote');
$query->condition('poll', $pollId, '=');
$query->range(0, 100);
$query->sort('id, 'DESC');
$query->condition('mandate.entity.fraction_membership.entity.fraction', fractionId);
$query->condition(
   $query->orConditionGroup()
      ->notExists('mandate.entity.fraction_membership.entity.valid_from')
      ->condition('mandate.entity.fraction_membership.entity.valid_from', $pollDate, '<=')
);
$query->condition(
   $query->orConditionGroup()
      ->notExists('mandate.entity.fraction_membership.entity.valid_until')
      ->condition('mandate.entity.fraction_membership.entity.valid_until', $pollDate, '>=')
);

There are two fraction_membership entities connected to a single mandate of a specific deupty because he changed his fraction membership:

The entries in fraction_membership table:

|  id   | fraction | valid_from | valid_until
|  123  |  22      |    NULL    | 2019-09-27
|  456  |  231     | 2019-09-28 |    NULL

The problem: with fraction 22 and poll date '2020-05-10' set as filters the vote of the deputy finds it's way into the result although there was no valid fraction membership at this time. The valid_until date for the fraction membership with fraction 22 (= 2019-09-27) is smaller than the poll date (= 2020-05-10). Fpr the given poll the vote of the deputy should only be in the results if the filter for the fraction was set to 231.

I checked the resulting query and for me it looks as if far too many joins are added. Could it be that this is the problem or did I make something wrong?

The resulting SQL query:

SELECT "base_table"."id" AS "id", "base_table"."id" AS "base_table_id"
FROM
{aw_vote_vote} "base_table"
INNER JOIN {aw_vote_vote} "aw_vote_vote" ON [aw_vote_vote].[id] = [base_table].[id]
LEFT OUTER JOIN {candidacies_mandates} "candidacies_mandates" ON [candidacies_mandates].[id] = [aw_vote_vote].[mandate]
INNER JOIN {candidacy_mandate__fraction_membership} "candidacy_mandate__fraction_membership" ON [candidacy_mandate__fraction_membership].[entity_id] = [candidacies_mandates].[id]
LEFT OUTER JOIN {fraction_membership} "fraction_membership" ON [fraction_membership].[id] = [candidacy_mandate__fraction_membership].[fraction_membership_target_id]
INNER JOIN {fraction_membership} "fraction_membership_2" ON [fraction_membership_2].[id] = [fraction_membership].[id]
LEFT JOIN {aw_vote_vote} "aw_vote_vote_2" ON [aw_vote_vote_2].[id] = [base_table].[id]
LEFT OUTER JOIN {candidacies_mandates} "candidacies_mandates_2" ON [candidacies_mandates_2].[id] = [aw_vote_vote_2].[mandate]
LEFT JOIN {candidacy_mandate__fraction_membership} "candidacy_mandate__fraction_membership_2" ON [candidacy_mandate__fraction_membership_2].[entity_id] = [candidacies_mandates_2].[id]
LEFT OUTER JOIN {fraction_membership} "fraction_membership_3" ON [fraction_membership_3].[id] = [candidacy_mandate__fraction_membership_2].[fraction_membership_target_id]
LEFT JOIN {fraction_membership} "fraction_membership_4" ON [fraction_membership_4].[id] = [fraction_membership_3].[id]
LEFT OUTER JOIN {candidacies_mandates} "candidacies_mandates_3" ON [candidacies_mandates_3].[id] = [aw_vote_vote_2].[mandate]
LEFT OUTER JOIN {fraction_membership} "fraction_membership_5" ON [fraction_membership_5].[id] = [candidacy_mandate__fraction_membership_2].[fraction_membership_target_id]
LEFT JOIN {fraction_membership} "fraction_membership_6" ON [fraction_membership_6].[id] = [fraction_membership_5].[id]
LEFT JOIN {aw_vote_vote} "aw_vote_vote_3" ON [aw_vote_vote_3].[id] = [base_table].[id]
LEFT OUTER JOIN {candidacies_mandates} "candidacies_mandates_4" ON [candidacies_mandates_4].[id] = [aw_vote_vote_3].[mandate]
LEFT JOIN {candidacy_mandate__fraction_membership} "candidacy_mandate__fraction_membership_3" ON [candidacy_mandate__fraction_membership_3].[entity_id] = [candidacies_mandates_4].[id]
LEFT OUTER JOIN {fraction_membership} "fraction_membership_7" ON [fraction_membership_7].[id] = [candidacy_mandate__fraction_membership_3].[fraction_membership_target_id]
LEFT JOIN {fraction_membership} "fraction_membership_8" ON [fraction_membership_8].[id] = [fraction_membership_7].[id]
LEFT OUTER JOIN {candidacies_mandates} "candidacies_mandates_5" ON [candidacies_mandates_5].[id] = [aw_vote_vote_3].[mandate]
LEFT OUTER JOIN {fraction_membership} "fraction_membership_9" ON [fraction_membership_9].[id] = [candidacy_mandate__fraction_membership_3].[fraction_membership_target_id]
LEFT JOIN {fraction_membership} "fraction_membership_10" ON [fraction_membership_10].[id] = [fraction_membership_9].[id]
WHERE ("aw_vote_vote"."poll" = :db_condition_placeholder_0) AND ("fraction_membership_2"."fraction" = :db_condition_placeholder_1) AND (("fraction_membership_4"."valid_from" IS NULL) or ("fraction_membership_6"."valid_from" >= :db_condition_placeholder_2)) AND (("fraction_membership_8"."valid_until" IS NULL) or ("fraction_membership_10"."valid_until" <= :db_condition_placeholder_3))
GROUP BY base_table.id
ORDER BY "base_table"."id" DESC
LIMIT 100 OFFSET 0
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.