Einen Feldwert abrufen, ohne den gesamten Knoten zu laden?

11

Ich habe eine große Anzahl von NIDs und benötige einen Feldwert von jedem Knoten. Gibt es eine Möglichkeit, den Aufwand für das Laden des gesamten Knotens zu vermeiden, um einen Feldwert zu erhalten?

Joren
quelle

Antworten:

19

Ich glaube nicht, dass irgendetwas in die API eingebaut ist, aber zur Not können Sie die Datenbank einfach direkt abfragen:

$entity_type = 'node';
$bundle = 'page';
$nids = array(1, 2, 3);

$field_values = db_select('field_revision_FIELD_NAME', 'f')
  ->fields('f', array('entity_id', 'FIELD_NAME_value'))
  ->condition('entity_type', $entity_type)
  ->condition('bundle', $bundle)
  ->condition('entity_id', $nids, 'IN')
  ->condition('deleted', 0)
  ->execute()
  ->fetchAllKeyed();

Nach dem Ausführen sollten Sie über ein Array von Feldwerten verfügen, die durch die NID des jeweiligen Knotens gekennzeichnet sind.

Es lohnt sich, sich daran zu erinnern, dass der Spaltenname nicht unbedingt sein muss FIELD_NAME_value. Beispielsweise hätte ein Knotenreferenzfeld den Spaltennamen FIELD_NAME_nid. Welches Sie verwenden, hängt von Ihrem Feldtyp ab.

AKTUALISIEREN

Es scheint, dass es eine Möglichkeit gibt, dies mit der API zu tun, aber es ist nicht schön und beinhaltet immer noch eine manuelle Abfrage:

// Get the field meta data for the field_id.
$field_name = 'field_something';
$field_info = field_info_field($field_name);
$field_id = $field_info['id'];

// Load up the properties from the node table.
$nids = array(1, 2, 3);
$sql = 'SELECT * FROM {node} WHERE nid IN (:nids)';
$nodes = db_query($sql, array(':nids' => $nids))->fetchAllAssoc('nid');

// Attach the single field to all nodes.
field_attach_load('node', $nodes, FIELD_LOAD_CURRENT, array('field_id' => $field_id));

Diese Methode nutzt den $optionsParameter in, field_attach_load()indem sie eine Feld-ID angibt, für die Daten geladen werden sollen. Es ist erwähnenswert, gemäß den Dokumenten:

Beachten Sie, dass zurückgegebene Entitäten Daten für andere Felder enthalten können, z. B. wenn sie aus einem Cache gelesen werden.

Der Code scheint also zusätzliche Felddaten zu laden, aber alles andere als das von Ihnen angegebene Feld stammt aus dem Cache.

Clive
quelle
Genial. Funktionierte perfekt und VIEL schneller als das Laden des gesamten Knotens.
Joren
Ich habe diesen Ansatz mit der Benutzerentität verwendet, um den Wert eines einzelnen Felds zu laden, aber diese Methode lädt alle Felder (und deren Werte), die dem Benutzerobjekt zugeordnet sind. Vermisse ich etwas
WM
Warnung: Das erste Beispiel erfordert das Speichern von Feldern in der SQL-Datenbank (Standard) und ist nicht mit alternativen Feldspeichern kompatibel. Die zweite sollte funktionieren (da sie field_attach_load verwendet und mit der Speicherabstraktion funktioniert).
Bobík
@Clive, gibt es einen Grund, warum Sie field_revision_FIELD_NAME anstelle von field_data_FIELD_NAME verwendet haben? Kannst du bitte Erklären? Vielen Dank.
Sandesh Yadav
3

Ich finde einen etwas saubereren Weg, wenn ich eine entityCondition und eine Feldanhangslast verwende.

$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
  ->entityCondition('bundle', 'story')
  ->propertyCondition('status', 1)
  ->fieldCondition('field_story_image', 'fid', 'NULL', '!=');
$result = $query->execute();

if (isset($result['node'])) {
  $stories = $result['node'];

  // At first we need to get field's id. If you already know field id, you can ommit this step
  // Get all fields attached to a given node type
  $fields = field_info_instances('node', 'story');

  // Get id of body field
  $field_id = $fields['field_story_image']['field_id'];

  // Attach a field of selected id only to get value for it
  field_attach_load('node', $stories, FIELD_LOAD_CURRENT, array('field_id' => $field_id));

  // Get values of our node field
  $output = field_get_items('node', $stories, 'field_story_image');
}

Aus dem Blog-Beitrag http://timonweb.com/loading-only-one-field-from-an-entity-or-node

gagarine
quelle
0

Um zu vermeiden, dass Knoten einzeln mit einer großen Anzahl von NIDs geladen werden, können Sie Folgendes verwenden, node_load_multiple()um mehrere Knoten gleichzeitig zu laden:

node_load_multiple($nids = array(), $conditions = array(), $reset = FALSE)

Normalerweise werden die Knoten zwischengespeichert und es ist schnell, wenn Sie Speicher-Caching verwenden (wie memcached), kann aber langsam sein, wenn zu viele Module installiert sind (wie Pathauto usw.).

Eine andere Möglichkeit besteht darin, das vorhandene Objekt wiederzuverwenden. Überprüfen Sie daher, ob Sie es direkt aus dem Cache (z. B. über, form_get_cacheob es Teil des Formulars ist) oder aus der $_POSTAnforderung laden können .

Eine andere Möglichkeit ist die Verwendung EntityFieldQuerymit mehreren NIDs, z

$query->entityCondition('entity_id', array(17, 21, 422), 'IN')

Dadurch werden die Werte direkt aus der Datenbank abgerufen.

Kenorb
quelle