it-swarm.com.de

Einen Feldwert abrufen, ohne den gesamten Knoten zu laden?

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?

11
Joren

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 FIELD_NAME_value Lautet. Beispielsweise hätte ein Knotenreferenzfeld den Spaltennamen FIELD_NAME_nid. Welches Sie verwenden, hängt von Ihrem Feldtyp ab.

[~ # ~] Update [~ # ~]

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 Parameter $options In field_attach_load() , indem eine Feld-ID angegeben wird, 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.

19
Clive

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

3
gagarine

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

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 laden können (z. B. über form_get_cache , wenn es Teil des Formulars ist) oder aus $_POST. Anfrage.

Eine andere Möglichkeit besteht darin, EntityFieldQuery mit mehreren NIDs zu verwenden, z.

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

dadurch werden die Werte direkt aus der Datenbank abgerufen.

0
kenorb