web-dev-qa-db-fra.com

Comment utiliser entityQuery pour sélectionner si un champ entityReference à plusieurs valeurs ne contient pas l'identifiant

J'ai une entité avec un champ entityReference utilisateur, qui peut contenir plusieurs valeurs. Je souhaite sélectionner à l'aide d'EntityQuery les nœuds qui ne contiennent PAS l'uid dans la requête.

$query
  ->condition('field_shared_with_user.target_id', $uid, '<>');

Cela ne fonctionne que pour exclure $ uid s'il n'y a qu'une seule valeur dans le champ. Si $ uid est présent mais qu'un autre uid est également présent, il inclut incorrectement ce nœud dans le résultat.

Quelle est la syntaxe correcte pour écrire une condition pour un champ à valeurs multiples?

Le plus que je puisse trouver sur l'écriture de ces requêtes est ici:

https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Entity!Query!QueryInterface.php/function/QueryInterface%3A%3Acondition/8

4
ransomweaver

gapple m'a mis sur la bonne voie (au moins une solution à mon problème spécifique), et c'est une combinaison de ses deux idées.

J'avais besoin de rechercher tous les nœuds qui référencent mon utilisateur, puis de rechercher toutes les entités qui correspondent à ma requête principale. cela me donne deux tableaux d'ID de nœud, et si je array_diff le premier à partir du 2ème, je me retrouve avec le tableau d'ID de nœud que je veux.

donc, une entité distincte Requête est nécessaire, mais ce n'est pas trop cher en calcul dans mon cas, je pense.

$my_contacts = \Drupal::entityQuery('node')
  ->condition('type', 'sc_card')
  ->condition('field_shared_with_user.target_id', $user->id())
  ->execute();
$public_contacts = \Drupal::entityQuery('node')
  ->condition('type', 'sc_card')
  ->condition('field_public_directory', true)
  ->execute();
$public_not_in_my_contacts = array_diff($public_contacts, $my_contacts);
3
ransomweaver

D'après ce que je comprends, l'Entity Query effectuera simplement une opération de jointure sur les tables, ce qui entraînera des données comme les suivantes:

entity.id | field_user.target
        1 |                 5
        1 |                 6
        2 |                 5

Une condition de jointure peut limiter les lignes renvoyées, mais restreinte par field_user.target <> 6 ne peut supprimer qu'une seule ligne (1:6), quittant le 1:5 ligne restante. Sans sous-requête, je ne pense pas qu'il existe un moyen d'exclure les deux lignes avec entity.id = 1.

Deux alternatives:

  • Exécutez une requête initiale pour trouver toutes les entités qui référencent l'utilisateur que vous souhaitez filtrer, puis filtrez votre requête par ces identifiants d'entité (essentiellement en faisant votre propre sous-requête).
  • Obtenez tous les résultats et filtrez-les dans PHP après.
2
gapple

Si vous voulez vérifier l'absence de valeur, vous devez utiliser notExists () au lieu de condition(). Il y a aussi un existe () .

0
colan