ฉันมี NID จำนวนมากและฉันต้องการค่าฟิลด์หนึ่งค่าจากแต่ละโหนด มีวิธีใดที่จะหลีกเลี่ยงโอเวอร์เฮดของการโหลดทั้งโหนดเพื่อรับค่าฟิลด์หนึ่งค่าหรือไม่?
ฉันมี NID จำนวนมากและฉันต้องการค่าฟิลด์หนึ่งค่าจากแต่ละโหนด มีวิธีใดที่จะหลีกเลี่ยงโอเวอร์เฮดของการโหลดทั้งโหนดเพื่อรับค่าฟิลด์หนึ่งค่าหรือไม่?
คำตอบ:
ฉันไม่คิดว่าจะมีอะไรใน 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
ตัวอย่างเช่นสนามโหนดอ้างอิงจะมีชื่อคอลัมน์ของ รูปแบบที่คุณใช้จะขึ้นอยู่กับประเภทเขตข้อมูลของคุณ
UPDATE
ดูเหมือนว่ามีวิธีที่จะทำกับ 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));
วิธีการดังกล่าวใช้ประโยชน์จาก$options
พารามิเตอร์field_attach_load()
โดยระบุ ID ฟิลด์เพื่อโหลดข้อมูล เป็นที่น่าสังเกตว่าต่อเอกสาร:
โปรดทราบว่าเอนทิตีที่ส่งคืนอาจมีข้อมูลสำหรับเขตข้อมูลอื่นตัวอย่างเช่นถ้าพวกเขาอ่านจากแคช
ดังนั้นรหัสอาจปรากฏขึ้นเพื่อโหลดข้อมูลเขตข้อมูลพิเศษ แต่สิ่งอื่นใดนอกเหนือจากเขตข้อมูลที่คุณระบุจะมาจากแคช
ฉันพบวิธีที่สะอาดขึ้นโดยใช้ 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
เพื่อหลีกเลี่ยงการโหลดโหนดทีละ 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')
ซึ่งจะดึงค่าโดยตรงจากฐานข้อมูล