Lấy một giá trị trường mà không tải toàn bộ nút?


11

Tôi có một số lượng lớn NID và tôi cần một giá trị trường từ mỗi nút. Có cách nào để tránh chi phí tải toàn bộ nút để nhận một giá trị trường không?

Câu trả lời:


19

Tôi không nghĩ có bất cứ điều gì được tích hợp trong API nhưng trong một vài trường hợp, bạn có thể truy vấn trực tiếp cơ sở dữ liệu:

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

Sau khi chạy, bạn sẽ có một mảng các giá trị trường, được khóa bởi nid của nút tương ứng.

Nó đáng để nhớ tên cột sẽ không nhất thiết phải là FIELD_NAME_value; ví dụ một trường tham chiếu nút sẽ có tên cột là FIELD_NAME_nid. Cái nào bạn sử dụng sẽ phụ thuộc vào loại trường của bạn.

CẬP NHẬT

Có vẻ như có một cách để làm điều đó với API, nhưng nó không hay và vẫn liên quan đến truy vấn thủ công:

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

Phương thức đó tận dụng $optionstham số field_attach_load()bằng cách chỉ định ID trường để tải dữ liệu. Đó là giá trị đáng chú ý, theo các tài liệu:

Lưu ý rằng các thực thể được trả về có thể chứa dữ liệu cho các trường khác, ví dụ nếu chúng được đọc từ bộ đệm.

Vì vậy, mã có thể đã xuất hiện để tải thêm dữ liệu trường, nhưng bất kỳ thứ gì khác ngoài trường bạn đã chỉ định sẽ đến từ bộ đệm.


Tuyệt vời. Hoạt động hoàn hảo và NHIỀU nhanh hơn tải toàn bộ nút.
Joren

Tôi đã sử dụng phương pháp này với thực thể người dùng để tải một giá trị của một trường nhưng phương thức này tải tất cả các trường (và giá trị của chúng) được liên kết với đối tượng người dùng. Tui bỏ lỡ điều gì vậy?
WM

Cảnh báo: Ví dụ đầu tiên yêu cầu lưu trữ các trường trong cơ sở dữ liệu SQL (mặc định) và không tương thích với các kho lưu trữ trường thay thế. Cái thứ hai sẽ hoạt động (vì nó sử dụng field_attach_load và nó sẽ hoạt động với sự trừu tượng hóa kho).
Bobík

@Clive, có bất kỳ lý do nào khiến bạn sử dụng field_Vvision_FIELD_NAME thay vì field_data_FIELD_NAME không? Bạn có thể vui lòng giải thích? Cảm ơn.
Sandesh Yadav

3

Tôi tìm thấy một cách sạch hơn một chút bằng cách sử dụng tải thực thể và trường đính kèm.

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

Từ bài đăng trên blog http://timonweb.com/loading-only-one-field-from-an-entity-or-node


0

Để tránh tải từng nút một có số lượng NID lớn, bạn có thể sử dụng node_load_multiple()sẽ tải nhiều nút cùng một lúc:

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

Thông thường tải các nút được lưu trong bộ nhớ cache và sẽ nhanh nếu bạn đang sử dụng bộ nhớ đệm (như memcached), nhưng có thể chậm nếu bạn cài đặt quá nhiều mô-đun (như Pathauto, v.v.) ..

Một cách khác là sử dụng lại đối tượng hiện có, vì vậy hãy kiểm tra xem bạn có thể tải nó trực tiếp từ bộ đệm hay không (ví dụ: form_get_cachenếu đó là một phần của biểu mẫu) hoặc từ $_POSTyêu cầu.

Một cách khác là sử dụng EntityFieldQueryvới nhiều NID, vd

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

sẽ lấy các giá trị trực tiếp từ cơ sở dữ liệu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.