web-dev-qa-db-fra.com

Effectuer une requête avec une condition de champ d'entité avec plusieurs valeurs

J'ai un type de contenu qui a un champ de référence d'entité qui permet aux utilisateurs d'ajouter plusieurs termes de taxonomie dans ce champ. J'essaie d'exécuter des requêtes qui récupèrent des nœuds qui ont un ensemble spécifique de termes de taxonomie dans ce champ.

Utiliser une valeur dans ce champ fonctionne très bien, comme ça.

    $query = \Drupal::entityQuery('node')
        ->condition('status', NODE_PUBLISHED)
        ->condition('type', 'custom_type')
        ->condition('custom_taxonomy', 2)
        ->sort('field_last_name', DESC);

Où 2 est l'ID du terme que je recherche. Cependant, lorsque j'essaie de rechercher des nœuds contenant deux termes spécifiques comme celui-ci,

    $query = \Drupal::entityQuery('node')
        ->condition('status', NODE_PUBLISHED)
        ->condition('type', 'custom_type')
        ->condition('custom_taxonomy', [2,8])
        ->sort('field_last_name', DESC);

Je reçois l'erreur

Numéro de paramètre non valide: le nombre de variables liées ne correspond pas au nombre de jetons:

J'ai aussi tenté

    $query = \Drupal::entityQuery('node')
        ->condition('status', NODE_PUBLISHED)
        ->condition('type', 'custom_type')
        ->condition('custom_taxonomy', [2,8], 'IN')
        ->sort('field_last_name', DESC);

Ce qui n'échoue pas, mais ne fournit pas les résultats escomptés. Il affiche tous les nœuds qui ont soit le terme 2 OU terme 8. Au lieu du terme 2 ET terme 8 comme prévu. Comment pourrais-je effectuer une requête qui vérifie si un nœud a plusieurs valeurs spécifiques dans un champ de référence d'entité?

14
Matt

Utilisez deux andConditionGroup() distinctes:

$query = \Drupal::entityQuery('node')
  ->condition('status', NODE_PUBLISHED)
  ->condition('type', 'custom_type');
$and = $query->andConditionGroup();
$and->condition('custom_taxonomy', 2);
$query->condition($and);
$and = $query->andConditionGroup();
$and->condition('custom_taxonomy', 8);
$query->condition($and);
$result = $query->execute();

Cela fonctionne quel que soit le nombre de termes dans le domaine ou dans quel delta ils se trouvent.

Modifier

Il en résulte ce SQL:

SELECT base_table.vid AS vid, base_table.nid AS nid
FROM 
{node} base_table
INNER JOIN {node_field_data} node_field_data ON node_field_data.nid = base_table.nid
INNER JOIN {node__custom_taxonomy} node__custom_taxonomy ON node__custom_taxonomy.entity_id = base_table.nid
INNER JOIN {node__custom_taxonomy} node__custom_taxonomy_2 ON node__custom_taxonomy_2.entity_id = base_table.nid
WHERE  (node_field_data.status = '1') AND (node_field_data.type = 'custom_type') AND( (node__custom_taxonomy.custom_taxonomy_target_id = '2') )AND( (node__custom_taxonomy_2.custom_taxonomy_target_id = '8') )
19
4k4

Pour effectuer des requêtes complexes comme vous l'avez demandé, vous devrez utiliser un groupe de conditions et interroger le delta.

$query = \Drupal::entityQuery('node');
$query->condition('status', NODE_PUBLISHED)
  ->condition('type', 'custom_type')
  ->condition('custom_taxonomy', [2, 8], 'IN')
  ->condition('custom_taxonomy.%delta', 2, '=')
  ->sort('field_last_name', DESC);
$or = $query->orConditionGroup();
$or->condition('custom_taxonomy.0.target_id', 2);
$or->condition('custom_taxonomy.0.target_id', 8);
$query->condition($or);

Voir QueryInterface :: condition documentation.

8
Eyal
$taxonomy_term = 'taxonomy_term';
    $vid = 'name_taxon';
    $terms = $this->entity_type_manager->getStorage($taxonomy_term)
      ->loadTree($vid);

foreach ($terms as $term) {
  $term_data[] = [
    "vid" => $term->vid,
    "name" => $term->name,
  ];
}
1
Viktor