it-swarm.com.de

entityQuery, um Knoten abzurufen, auf die andere Knoten wie SQL JOIN verweisen

Ich habe eine Entitätsabfrage, um Inhalte vom Typ article abzurufen, die ein Feld haben, das einem bestimmten Wert entspricht, was wie erwartet funktioniert.

$query = \Drupal::entityQuery('node');
$query->condition('status', 1);
$query->condition('type', 'article');
$query->condition('field_some_field', 'some value');

Jetzt habe ich einen zweiten Inhaltstyp detail_page, Der einen Entitätsverweis auf einen Knoten vom Typ article enthält. Ich möchte Inhalte vom Typ article, wie zuvor erhalten, aber nur diejenigen, auf die im Feld field_detail_page_article_ref Eines detail_page Verwiesen wurde. Inhaltstyp.

Ist das mit Entitätsabfragen möglich? Wenn ich mit dem unformatierten SQL herumspiele, muss ich im Grunde ein INNER JOIN Oder LEFT JOIN Mit dem Feld field_detail_page_article_ref Tun, um zu sehen, ob das nid existiert. Es scheint jedoch nicht, dass für Entitätsabfragen irgendeine Funktion join() verfügbar ist.

4
The Unknown Dev

Ich hatte gerade genau das gleiche Problem mit einer Drupal 8-Instanz, und obwohl ich es nicht mit einer einzigen Abfrage lösen konnte, wie ich es gerne hätte, war ich mit der erfolgreich Folgendes:

Mein Ziel war es, alle Knoten vom Typ A oder B zu erhalten, die bestimmte Kriterien erfüllen. Eines davon ist, dass sie vom Typ C referenziert werden. (Ich habe das andere Zeug hier entfernt, um mich auf das Problem zu konzentrieren.) Typ hat eine Entität Referenzfeld, das mehrere Einträge für Typ A oder B ermöglicht.

Zuerst erhalten wir alle Nids, auf die verwiesen wird:

$connection = \Drupal::database();
$query = $connection->query("SELECT DISTINCT field_name_target_id  FROM {node__field_name}");
$referenced_nids = $query->fetchCol();

Beachten Sie, dass Sie Ihren Code an den Namen Ihres Referenzfelds anpassen müssen. Siehe https://www.drupal.org/docs/8/api/database-api/static-queries , von wo ich das Bit gerissen habe.

Dann meine Abfrage, um die tatsächlichen Knoten/Nids zu erhalten:

$storage = \Drupal::entityTypeManager()->getStorage('node');

$query = $storage->getQuery();

$nids = $query->condition('type', ['TypeA', 'TypeB'], 'IN')
  ->condition('status', 1)
  ->condition('nid', $referenced_nids, 'IN')
  ->sort('title')
  ->execute();

UPDATE: Ich habe heute erfahren, dass der erste Schritt meines Verfahrens nach Drupal-Standards, wie Sie sollten, nicht als richtig angesehen wird) Keine direkten Abfragen für Drupal -Tabellen (siehe https://www.drupal.org/core/d8-bc-policy#schema ). Die folgende Methode ist leider brutaler, aber das Zwischenspeichern der Ergebnisse sollte helfen.

Stattdessen habe ich den ersten Teil mit einer EntityQuery überarbeitet.

// Get all the entities of type C, the referencing entity:
$query = \Drupal::entityQuery('node')
  ->condition('type', 'TypeC')
  ->condition('status', 1);
$typeC_nids = $query->execute();
$typeC_nodes = $storage->loadMultiple($typec_nids);

// Loop through the nodes and get all the references:
$referenced_nids = [];
foreach ($typeC_nodes as $node) {
 $references = array_column($node->field_name->getValue(), 'target_id');
 foreach ($references as $reference) {
   if (!in_array($reference, $referenced_nids)) {
     $referenced_nids[] = $reference;
   }
 }

}}

Verwenden Sie dann diese Liste der referenzierten NIDs in der zweiten Abfrage.

3
beltouche

Sie können Feldabfrage 'Entität' verwenden

$query = \Drupal::entityQuery('node');
$query->condition('status', 1);
$query->condition('type', 'article');
$query->condition('field_some_field.entity:node.title', 'Referenced node title');
10
gambry