web-dev-qa-db-fra.com

Récupérer une valeur de champ sans charger le nœud entier?

J'ai un grand nombre de NID et j'ai besoin d'une valeur de champ de chaque nœud. Existe-t-il un moyen d'éviter la surcharge de chargement du nœud entier pour obtenir une valeur de champ?

11
Joren

Je ne pense pas qu'il y ait quelque chose de intégré à l'API, mais en un clin d'œil, vous pouvez simplement interroger la base de données directement:

$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();

Après avoir exécuté cela, vous devriez avoir un tableau de valeurs de champ, saisies par le nid de leur nœud respectif.

Il convient de se rappeler que le nom de la colonne ne sera pas nécessairement FIELD_NAME_value; par exemple, un champ de référence de nœud aurait un nom de colonne de FIELD_NAME_nid. Lequel vous utiliserez dépendra de votre type de champ.

[~ # ~] mise à jour [~ # ~]

Il semble qu'il existe un moyen de le faire avec l'API, mais ce n'est pas joli et implique toujours une requête manuelle:

// 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));

Cette méthode tire parti du paramètre $options Dans field_attach_load() en spécifiant un ID de champ pour lequel charger les données. Il convient de noter, selon la documentation:

Notez que les entités renvoyées peuvent contenir des données pour d'autres champs, par exemple si elles sont lues dans un cache.

Le code peut donc sembler charger des données de champ supplémentaires, mais tout autre que le champ que vous avez spécifié proviendra du cache.

19
Clive

Je trouve un moyen un peu plus propre en utilisant un entityCondition et une charge d'attache de champ.

$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');
}

Extrait du blog http://timonweb.com/loading-only-one-field-from-an-entity-or-node

3
gagarine

Pour éviter de charger un nœud un par un avec un grand nombre de NID, vous pouvez utiliser node_load_multiple() qui chargera plusieurs nœuds à la fois:

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

Normalement, le chargement des nœuds est mis en cache et c'est rapide si vous utilisez la mémoire cache (comme memcached), mais cela pourrait être lent si vous avez trop de modules installés (comme Pathauto, etc.).

Une autre façon est de réutiliser l'objet existant, alors vérifiez si vous pouvez le charger directement à partir du cache (par exemple via form_get_cache si cela fait partie du formulaire) ou de $_POST demande.

Une autre façon consiste à utiliser EntityFieldQuery avec plusieurs NID, par exemple.

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

qui va récupérer les valeurs directement à partir de la base de données.

0
kenorb