Mengambil nilai bidang tanpa memuat seluruh node?


11

Saya memiliki sejumlah besar NID dan saya perlu satu nilai bidang dari setiap node. Apakah ada cara untuk menghindari overhead memuat seluruh node untuk mendapatkan satu nilai bidang?

Jawaban:


19

Saya tidak berpikir ada sesuatu yang dibangun di dalam API tetapi dalam keadaan darurat Anda bisa menanyakan database secara langsung:

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

Setelah menjalankan itu Anda harus memiliki array nilai bidang, dikunci oleh nid masing-masing node.

Patut diingat bahwa nama kolom belum tentu FIELD_NAME_value; misalnya bidang referensi simpul akan memiliki nama kolom FIELD_NAME_nid. Yang mana yang Anda gunakan akan tergantung pada jenis bidang Anda.

MEMPERBARUI

Tampaknya ada cara untuk melakukannya dengan API, tetapi itu tidak cantik dan masih melibatkan permintaan manual:

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

Metode itu memanfaatkan $optionsparameter field_attach_load()dengan menetapkan ID bidang untuk memuat data. Perlu dicatat, per dokumen:

Perhatikan bahwa entitas yang dikembalikan dapat berisi data untuk bidang lain, misalnya jika mereka dibaca dari cache.

Jadi kode tersebut mungkin muncul untuk memuat data bidang tambahan, tetapi apa pun selain bidang yang Anda tentukan akan berasal dari cache.


Luar biasa. Bekerja dengan sempurna dan JAUH lebih cepat daripada memuat seluruh node.
Joren

Saya telah menggunakan pendekatan ini dengan entitas pengguna untuk memuat nilai bidang tunggal tetapi metode ini memuat semua bidang (dan nilai-nilainya) yang terkait dengan objek pengguna. Apakah saya melewatkan sesuatu?
WM

Peringatan: Contoh pertama mengharuskan untuk menyimpan bidang dalam database SQL (default) dan tidak kompatibel dengan penyimpanan bidang alternatif. Yang kedua harus bekerja (karena menggunakan field_attach_load dan itu akan bekerja dengan abstraksi penyimpanan).
Bobik

@Clive, apakah ada alasan Anda menggunakan field_revision_FIELD_NAME alih-alih field_data_FIELD_NAME? Bisakah Anda jelaskan? Terima kasih.
Sandesh Yadav

3

Saya menemukan cara yang sedikit lebih bersih menggunakan entityCondition dan field attach load.

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

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


0

Untuk menghindari pemuatan simpul satu per satu yang memiliki NID dalam jumlah besar, Anda dapat menggunakan node_load_multiple()yang akan memuat banyak node sekaligus:

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

Biasanya memuat node di-cache dan cepat jika Anda menggunakan cache memori (seperti memcached), tetapi bisa lambat jika Anda sudah menginstal terlalu banyak modul (seperti Pathauto, dll).

Cara lain adalah dengan menggunakan kembali objek yang ada, jadi periksa apakah Anda dapat memuatnya langsung dari cache (mis. Via form_get_cacheapakah itu bagian dari formulir) atau dari $_POSTpermintaan.

Cara lain adalah menggunakan EntityFieldQuerydengan beberapa NID, mis

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

yang akan mengambil nilai langsung dari database.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.