전체 노드를로드하지 않고 필드 값을 검색 하시겠습니까?


11

NID가 많고 각 노드에서 하나의 필드 값이 필요합니다. 하나의 필드 값을 얻기 위해 전체 노드를로드하는 오버 헤드를 피할 수있는 방법이 있습니까?

답변:


19

API에 내장 된 것이 없다고 생각하지만 핀치로 데이터베이스를 직접 쿼리 할 수 ​​있습니다.

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

실행 한 후에는 해당 노드의 nid를 기준으로 배열 된 필드 값 배열이 있어야합니다.

열 이름을 반드시 기억할 필요는 없습니다 FIELD_NAME_value. 예를 들어, 노드 참조 필드의 열 이름은 FIELD_NAME_nid입니다. 사용하는 것은 필드 유형에 따라 다릅니다.

최신 정보

API로 할 수있는 방법이있는 것 같지만 예쁘지 않고 여전히 수동 쿼리가 필요합니다.

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

이 메소드는 데이터를로드 할 필드 ID를 지정 하여 $options매개 변수를 활용 field_attach_load()합니다. 문서별로 주목할 가치가 있습니다.

리턴 된 엔티티는 다른 필드에 대한 데이터를 포함 할 수 있습니다 (예 : 캐시에서 읽은 경우).

따라서 코드에서 추가 필드 데이터를로드하는 것처럼 보이지만 지정한 필드 이외의 것은 캐시에서 비롯됩니다.


대박. 전체 노드를로드하는 것보다 완벽하고 빠르게 작동했습니다.
Joren

이 방법을 사용자 엔터티와 함께 ​​사용하여 단일 필드의 값을로드했지만이 방법은 사용자 개체와 관련된 모든 필드 (및 해당 값)를로드합니다. 뭔가 빠졌습니까?
WM

경고 : 첫 번째 예는 SQL 데이터베이스에 필드를 저장해야하며 (기본값) 대체 필드 스토리지와 호환되지 않습니다. 두 번째는 field_attach_load를 사용하고 스토리지 추상화와 함께 작동하기 때문에 작동해야합니다.
Bobík

@Clive, field_data_FIELD_NAME 대신 field_revision_FIELD_NAME을 사용한 이유가 있습니까? 설명해 주시겠습니까? 감사.
Sandesh Yadav

3

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

블로그 게시물 http://timonweb.com/loading-only-one-field-from-an-entity-or-node


0

많은 수의 NID가있는 노드를 하나씩로드하지 않으려면 한 번에 node_load_multiple()여러 노드를로드 할 수 있습니다 .

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

일반적으로 노드로드는 캐시되며 메모리 캐싱 (예 : memcached)을 사용하면 빠르지 만 너무 많은 모듈 (Pathauto 등)을 설치하면 느려질 수 있습니다.

다른 방법은 기존 객체를 재사용하는 것이므로 캐시에서 직접로드 할 수 있는지 (예 : form_get_cache폼의 일부인 경우) $_POST요청 에서로드 할 수 있는지 확인하십시오 .

다른 방법은 EntityFieldQuery여러 NID와 함께 사용하는 것 입니다.

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

데이터베이스에서 직접 값을 가져옵니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.