두 개의 뷰를 결합하는 방법은 무엇입니까?


36

"노트 날짜"별로 정렬 된 사용자 노드와 주석을 통합하려고합니다. 이 게시물 은 D6의 샌드 박스 프로젝트에 연결되지만 7에는 없습니다.

게시물 에는 D6에서 hook_views_pre_execute () 및 SQL UNION을 사용하는 예가 있습니다. 뷰가 3 인 D7에서는 작동하지 않습니다.

나는 merlinofchaos의 의견을 발견했다

우리는 이제 Drupal의 새로운 쿼리 생성기를 사용하고 있기 때문에 쿼리는 수정하거나 교체해야하는 SelectQuery 개체입니다. 자세한 내용은 Drupal 7의 새로운 데이터베이스 계층을 찾아보십시오.

누구 든지이보기 또는 다른 솔루션을 사용하여 두 가지 견해를 결합하는 방법에 대한 예가 있습니까?


이것은 실제 답변보다 더 많은 아이디어입니다. 사용자를 기반으로 뷰를 만들 수 있어야합니다.이 노드는 노드와 주석 모두에 합류 할 것입니다 (결국 모두 엔티티 일뿐입니다). 첫 번째 시도에서 뷰가 사용자와 coment 사이의 관계를 제공하지 않기 때문에이 작업을 수행하지 못했습니다. 그러나 변경하기 쉬워야합니다. (또는 방금 무언가를 잊어 버렸습니다).
mojzis

kt는 두 가지 컨텍스트 필터가 필요합니다 (content.author = 사용자 로그인 또는 comment.author = 로그인 사용자).
uwe

나는 그렇게 생각하지 않습니다 :) 나는 노드와 의견에 합류하여 사용자를 기반으로 한보기를 의미합니다. 그러나 사용자와 의견 사이의 관계에 문제가 있다고 생각합니다. 의견을 표시하지 못했습니다.
mojzis

방금 추측하지만 searchapi를 사용하여 여러 엔티티 유형을 동시에 색인 할 수 없습니까? 일단 당신이 그것을 가지고 당신이 두 부분에 의해 사용되는 필드를 가지면 당신은 그것을 그렇게보기 좋게 사용할 수 있습니다.
Daniel Wehner

1
drupal 7 용 샌드 박스 프로젝트 'Views Unionize'가 있습니다. 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 UNION을 만든 다음 theme () 함수를 사용하여 호출기를 포함한 테이블 레이아웃으로 렌더링했습니다.

사용자에게는 기본보기처럼 보입니다. 다른 장점은 쿼리를 많이 최적화 할 수 있다는 것입니다. 나는 "내 친구의 활동"을 보여주고 있는데, 만약 당신이 그것에 대한 뷰를 사용한다면 그것은 당신의 친구리스트를 생성하고 당신이 50 개 또는 100 개 이상의 레코드를 가지고 있다면 매우 느린 SQL "IN"절에서 그것을 사용할 것입니다.

지난 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


이것이 가능할 수있는 유일한 방법은 두보기가 거의 동일 할 경우입니다.
Dalin

0

Views Field View 라는 모듈 을 보았습니다.이 뷰를 다른 뷰에 필드로 포함시킬 수 있습니다. 아직 직접 시도하지는 않았지만 도움이 될 수 있습니다.


2
Views Field View는 실제로 주석과 노드를 모두 얻을 수 있지만 필드 내에서만 필드를 정렬하는 방법이 없다고 생각합니다.
Letharion 2016 년

0

EntityFieldQuery는 백엔드 뷰 동시에 여러 개체 유형에 대한 지원 쿼리를. 따라서 노드와 주석을 모두 쿼리 할 수 ​​있어야합니다. 두 엔티티 유형 모두 uid특성을 사용하여 작성자에게 링크하므로 API 레벨에서 EntityFieldQuery :: propertyCondition () 을 사용하여 단일 사용자로부터 노드 및 주석을 선택할 수 있어야합니다. 뷰 백엔드가 동일한 기능을 제공한다고 생각합니다.


여러 엔티티를 쿼리하는 기능을 방금 삭제 한 것 같습니다. drupal.org/node/1564740
uwe

0

다른 접근 방법은 만들 수 피드 (URL에 사용자의 식별자의 상황에 맞는 필터) 노드와 코멘트를 한 다음 새 피드로 두 개의 피드를 결합, 사후 날짜별로이 표시됩니다.


-2

사용 된 글로벌 : PHP 필드? 이 두 가지를 결합한 View를 함께 덕트로 연결하는 데 사용할 수 있습니다.

컨텐츠 : 제목 및 컨텐츠 : 주석 필드 (표시에서 제외)를 사용하여 컨텐츠보기를 작성하십시오.

사용자가 최근에 작성한 날짜, 마지막 업데이트 날짜 또는 마지막 주석 날짜를 계산하는 PHP 필드를 추가하고 필드 값을 해당 날짜로 설정하십시오. 해당 필드를 정렬 조건으로 추가하십시오.

주석 또는 노드에 대한 링크를 출력하는 유사한 필드를 추가하십시오.

나에게 좋은 소리!


흥미로운 생각. 두 개의 컨텍스트 필터가 필요합니다 (content.author = 사용자 로그인 또는 comment.author = 로그인 사용자).
uwe

이것에 대한 서사시 회복을 기대하고 ...;)
Johnathan Elmore

2
이 접근 방식으로 인한 성능 저하는 무섭습니다. 수행 된 잠재적 인 데이터베이스 쿼리 수는 천문학적 문제에 영향을 줄 수 있습니다.
Rider_X
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.