วิธีการสร้างสหภาพของสองมุมมองได้อย่างไร


36

ฉันกำลังพยายามรวมกลุ่มโหนดและความคิดเห็นของผู้ใช้ที่เรียงลำดับตาม "วันที่โพสต์" โพสต์นี้ลิงก์ไปยังโครงการ sandbox สำหรับ D6 แต่ไม่มีอะไรสำหรับ 7

โพสต์นี้มีตัวอย่างการใช้ hook_views_pre_execute () และ SQL UNION ใน D6 สิ่งนี้ใช้ไม่ได้กับ D7 ที่มีมุมมอง 3

ฉันเจอความคิดเห็นของ merlinofchaos

เนื่องจากขณะนี้เรากำลังใช้ตัวสร้างคิวรีใหม่ของ Drupal การสืบค้นจึงเป็นวัตถุ SelectQuery ซึ่งคุณจะต้องแก้ไขหรือแทนที่ ค้นหาเลเยอร์ฐานข้อมูลใหม่ของ Drupal 7 สำหรับข้อมูลเพิ่มเติม

ไม่มีใครมีตัวอย่างของวิธีการทำเช่นนี้หรือวิธีอื่น ๆ เพื่อรวมสองมุมมอง?


นี่เป็นแนวคิดมากกว่าคำตอบที่แท้จริง: คุณควรจะสามารถสร้างมุมมองตามผู้ใช้ซึ่งจะเข้าร่วมทั้งโหนดและความคิดเห็น (ไม่ใช่ทั้งสองหน่วยงานหลังจากทั้งหมด :) ในความพยายามครั้งแรกของฉันฉันไม่สามารถทำสิ่งนี้ได้เพราะมุมมองไม่ได้เสนอความสัมพันธ์จากผู้ใช้กับ coment แต่นั่นควรจะง่ายที่จะเปลี่ยนแปลง (หรือฉันแค่ลืมบางสิ่ง)
mojzis

ฉันคิดว่ามันเป็นคำตอบเดียวกับด้านล่าง: kt ต้องการตัวกรองตามบริบทสองตัว (content.author = ผู้ใช้ที่เข้าสู่ระบบหรือผู้ใช้ comment.author = ผู้ใช้ที่เข้าสู่ระบบ)
uwe

ฉันไม่คิดอย่างนั้น :) ฉันหมายถึงมุมมองที่อิงจากผู้ใช้เข้าร่วมโหนดและความคิดเห็น แต่ฉันมีความรู้สึกว่ามีปัญหาบางอย่างเกี่ยวกับความสัมพันธ์ระหว่างผู้ใช้และความคิดเห็น - ฉันไม่ได้จัดการที่จะแสดงความคิดเห็น
mojzis

ฉันแค่เดา ​​แต่คุณไม่สามารถใช้ searchapi เพื่อจัดทำดัชนีเอนทิตีหลายประเภทในเวลาเดียวกันได้หรือไม่ เมื่อคุณมีและคุณมีเขตข้อมูลซึ่งใช้โดยทั้งสองส่วนคุณสามารถใช้มันเพื่อสร้างมุมมองแบบนั้น
Daniel Wehner

1
มีโครงการ sandbox 'Views Unionize' สำหรับ drupal 7 โปรดตรวจสอบdrupal.org/sandbox/jalama/1785294 ,
Anoop Joseph

คำตอบ:


15

นี่คือตัวอย่างการทำงานและทดสอบ:

/**
 * Implements hook_views_pre_execute().
 */
function mymodule_views_pre_execute(view &$view) {
  if ($view->name == 'my_view') {
    $query1 = &$view->build_info['query'];

    // Basic setup of the second query.
    $query2 = db_select('another_table', 'at')
      ->condition('some_field', 0, '>')
      ->condition('some_other_field', 12345);

    // The number of fields (and their aliases) must match query1.
    // Get the details with:
    // dpm($query1->getFields());
    $query2->addField('at', 'some_field', 'alias1');
    $query2->addField('at', 'some_other_field', 'alias2');
    $query2->addField('at', 'some_other_field2', 'alias3');
    $query2->addField('at', 'some_other_field3', 'alias4');

    // Verify that queries are very similar.
    // dpq($query1);
    // dpq($query2);

    // Matrimony.
    $query1 = $query2->union($query1, 'UNION ALL');

    // Manual test.
    // dpm($query1->execute()->fetchAll());

  }
}

มันใช้งานได้กับมุมมองส่วนใหญ่ อย่างไรก็ตามปลั๊กอินสไตล์บางอย่างอาจทำสิ่งแฟนซีที่จะไม่ทำงานกับเทคนิคนี้ (โมดูลปฏิทินฉันกำลังมองคุณอยู่)



2

ฉันลงเอยด้วยการใช้ db_query () เพื่อสร้าง SQL UNIONs จากนั้นแสดงผลเป็นเค้าโครงตารางรวมถึงวิทยุติดตามตัวที่ใช้ฟังก์ชัน theme ()

สำหรับผู้ใช้ดูเหมือนกับมุมมองเริ่มต้น ประโยชน์อื่น ๆ คือฉันสามารถเพิ่มประสิทธิภาพการค้นหาได้มาก ฉันกำลังแสดง "กิจกรรมของเพื่อนของฉัน" และถ้าคุณจะใช้มุมมองเพื่อที่จะสร้างรายชื่อเพื่อนของคุณและใช้มันในประโยค "IN" ของ SQL ซึ่งช้ามากถ้าคุณมีมากกว่า 50 หรือ 100 บันทึก

ฉันสามารถ จำกัด รายชื่อเพื่อนให้แคบลงได้เฉพาะคนที่เข้าสู่ระบบของเว็บไซต์ในช่วง x วันที่ผ่านมา

นี่คือตัวอย่างโค้ด:

  // Two queries are required (friendships can be represented in 2 ways in the
  // same table). No point making two db calls though so a UNION it is.

  // Build up the first query.
  $query = db_select('flag_friend', 'f')
    ->condition('f.uid', $account->uid)
    ->condition('u.login', $timestamp, '>');
  $query->addExpression('f.friend_uid', 'uid');
  $query->innerJoin('users', 'u', 'u.uid = f.friend_uid');

  // Build up the second query.
  $query2 = db_select('flag_friend', 'f')
    ->condition('f.friend_uid', $account->uid)
    ->condition('u.login', $timestamp, '>');
  $query2->addExpression('f.uid', 'uid');
  $query2->innerJoin('users', 'u', 'u.uid = f.uid');

  // Return the results of the UNIONed queries.
  return $query->union($query2)->execute()->fetchCol();

1

สำหรับการอ้างอิงในอนาคตนี่คือวิธีที่ฉันรวมสองมุมมองโดยอิงจากตารางเดียวกันเข้าด้วยกัน หลักการเดียวกันนี้ควรนำไปใช้กับมุมมองโดยพิจารณาจากตารางที่แตกต่างกันซึ่งมีจำนวนฟิลด์เท่ากัน

ในกรณีด้านล่างจะมีการเลือกเฉพาะ ID เนื่องจากรูปแบบถูกตั้งค่าเป็นเอนทิตีที่แสดงผล แต่ถ้าคุณจะไปกับเขตข้อมูลคุณสามารถเพิ่มเขตข้อมูลจำลองเพิ่มเติมลงในแบบสอบถามที่มีเขตข้อมูลน้อยลงเมื่อฉันเพิ่มการประทับเวลาด้านล่าง

/**
 * Implements hook_views_pre_execute().
 */
function MY_MODULE_views_pre_execute(&$view) {
  if ($view->name == 'VIEW_1' && $view->current_display == 'DISPLAY_OF_VIEW_1') {

    $view2 = views_get_view('VIEW_2');
    $view2->build('DISPLAY_OF_VIEW_2');

    $view->build_info['query']
    ->fields('table_alias', array('timestamp'))
    ->union(
        $view2->build_info['query']
        ->range()
        ->fields('table_alias', array('timestamp'))
        ->orderBy('timestamp', 'DESC')
    );

    $view->build_info['count_query']
    ->union(
        $view2->build_info['count_query']
        ->range()
    );
  };
}

0

ฉันจินตนาการถึงบางสิ่งตามบรรทัดเหล่านี้:

/** 
* Implements hook_views_pre_execute().
*/     
function mymodule_views_pre_execute(&$view) {
  if ($view->name == 'myview') {
    $query = $view->query;
    $other_view = views_get_view('otherview');
    $other_query = $other_view->query;
    $query = $query->union($other_query);
    $view->query = $query;
  }
}

แม้ว่าฉันจะไม่ได้ทดสอบ

ลิงก์บางอย่างที่อาจช่วย:

http://api.drupal.org/api/drupal/includes!database!select.inc/function/SelectQueryInterface%3A%3Aunion/7

http://drupal.org/node/557318#comment-1991910


1
ดูเหมือนว่ามันจะไม่ทำงานอย่างเต็มที่ $ view-> query เป็นวัตถุระดับกลางที่ Views ใช้ในการสร้างแบบสอบถาม SelectQuery คือ $ view-> build_info ['query'] เมื่อคุณแก้ไขตามลำดับฉันไม่สามารถเกินข้อผิดพลาด "ข้อผิดพลาดร้ายแรง: วิธีการโทรไปยังไม่ได้กำหนด SelectQuery :: render_pager ()"
mpdonadio

1
รหัสการทดสอบฐานข้อมูลมีตัวอย่างของสหภาพapi.drupal.org/api/drupal/ …และapi.drupal.org/api/drupal/ …
mikeytown2

อีกหนึ่งตัวอย่างที่drupal.org/node/748844#comment-7070234
Uwe

วิธีเดียวที่อาจเป็นไปได้คือถ้ามุมมองทั้งสองใกล้เคียงกัน
Dalin

0

ฉันเจอโมดูลที่เรียกว่าViews Field Viewซึ่งให้คุณฝังมุมมองเป็นฟิลด์ในมุมมองอื่น ฉันยังไม่ได้ลองเลย แต่ก็อาจเป็นประโยชน์กับคุณได้


2
ในขณะที่ Views Field View สามารถรับทั้งความคิดเห็นและโหนดได้ แต่ฉันไม่เชื่อว่าจะมีวิธีการเรียงลำดับข้ามฟิลด์ได้เฉพาะภายในเท่านั้น
Letharion

0

EntityFieldQuery ชม Backendสอบถามการสนับสนุนสำหรับประเภทกิจการที่หลายคนในเวลาเดียวกัน ดังนั้นจึงควรใช้งานได้เพื่อค้นหาทั้งโหนดและข้อคิดเห็น เอนทิตีทั้งสองชนิดใช้uidคุณสมบัติเพื่อลิงก์ไปยังผู้เขียนดังนั้นในระดับ API EntityFieldQuery :: propertyCondition ()ควรใช้งานเพื่อเลือกโหนดและข้อคิดเห็นจากผู้ใช้คนเดียว ฉันเดาว่าแบ็กเอนด์มุมมองให้คุณสมบัติเดียวกัน


ดูเหมือนว่าพวกเขาเพิ่งลบคุณลักษณะเพื่อสืบค้นหลายเอนทิตี: drupal.org/node/1564740
uwe

0

วิธีการที่แตกต่างกันอาจสร้างฟีดของโหนดและข้อคิดเห็น (ด้วยตัวกรองเชิงบริบทของตัวระบุผู้ใช้ใน URL) จากนั้นรวมฟีดทั้งสองเข้ากับฟีดใหม่และแสดงสิ่งนี้ตามวันที่โพสต์


-2

ใช้Global:ฟิลด์PHPหรือไม่ คุณสามารถใช้พวกมันเพื่อพันเทปเข้าด้วยกันเป็นมุมมองที่รวมทั้งสองอย่างเข้าด้วยกัน

สร้างมุมมองเนื้อหาที่มีเนื้อหา: ฟิลด์ชื่อและเนื้อหา: ความคิดเห็น (ยกเว้นจากจอแสดงผล)

เพิ่มฟิลด์ PHP ที่คำนวณว่าเป็นวันที่ล่าสุดวันที่อัพเดตล่าสุดหรือวันที่ความคิดเห็นล่าสุดโดยผู้ใช้และตั้งค่าของฟิลด์เป็นวันที่นั้น เพิ่มเขตข้อมูลนั้นเป็นเงื่อนไขการจัดเรียง

เพิ่มฟิลด์ที่คล้ายกันซึ่งแสดงลิงก์ไปยังข้อคิดเห็นหรือโหนด

มันฟังดูดีสำหรับฉัน!


ความคิดที่น่าสนใจ มันจะต้องมีตัวกรองตามบริบทสองตัว (content.author = ผู้ใช้ที่เข้าสู่ระบบหรือ comment.author = ผู้ใช้ที่เข้าสู่ระบบ)
uwe

หวังว่าจะได้รับการฟื้นฟูครั้งใหญ่ในครั้งนี้ ... ;)
Johnathan Elmore

2
ประสิทธิภาพที่ได้จากวิธีนี้น่ากลัวมาก จำนวนการสืบค้นฐานข้อมูลที่เป็นไปได้อาจเพิ่มขึ้นในทางดาราศาสตร์
Rider_X
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.