LARAVEL - 많은 다형성 관계에서 태그를 기반으로 검색하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com//questions/24024121

문제

텍스트 입력 및 다중 선택 입력으로 설정된 양식이 있습니다. 다중 선택 입력에는 태그 목록이 있습니다. 태그는 다형성 관계로 설정됩니다. 일을 분명히하기 위해 아래는 내 테이블과 모델의 개요입니다.

테이블 :

org
   id - integer
   name - text
   ...

tags
   id - integer
   name - text

taggables
   tag_id - integer
   taggable_id - integer
   taggable_type - text
.

모델 :

class Org extends Eloquent
{
    ...

    public function tags()
    {
        return $this->morphToMany('Tag', 'taggable');
    }
}


class Tag extends Eloquent
{
    ...

    public function org() 
    {
        return $this->morphedByMany('Org', 'taggable');
    }
}
.

내 ROUTES.PHP 파일에서 나는 그렇게 검색을 수행하려고합니다 ...

$search = Input::get('keyword');
$searchTerms = explode(' ', $search);
$query = Org::query();
$fields = array('name', 'description', 'additional_info', 'website');

foreach ($searchTerms as $term)
{
    foreach ($fields as $field)
    {
        $query->orWhere($field, 'LIKE', '%'. $term .'%');
    }
}

if(Input::get('tags'))
{
    $tags = Input::get('tags');
    $query
        ->join('taggables', 'taggables.taggable_id', '=', 'org.id')
        ->where('taggables.taggable_type', '=', 'Org')
        ->join('tags', 'taggables.tag_id', '=', 'tags.id')
        ->groupBy('org.id');

    foreach ($tags as $tag)
    {
        $query->orWhere('tags.id', '=', $tag);
    }
}

$org = $query->get();
.

그러나 이것은 물론 작동하지 않습니다. 키워드 검색은 잘 작동하지만 지정된 연관된 태그가있는 행만 검색 할 쿼리를 추가하는 방법을 모르겠습니다. $ TAGS 변수는 태그의 ID가 포함 된 배열입니다.

배열에 지정된 태그 중 적어도 하나가있는 org 테이블의 행만 반환하고 싶습니다.

업데이트 : 저는 코드를 업데이트했으며 일종의 작품을 업데이트했지만 연관된 조직이 아닌 태그를 반환하는 것으로 보입니다. 다음은 내가 추가 한 코드가 추가되었거나 위의 내용을 보았습니다.

$query
    ->join('taggables', 'taggables.taggable_id', '=', 'org.id')
    ->join('tags', 'taggables.tag_id', '=', 'tags.id')
    ->where('taggables.taggable_type', '=', 'Org')
    ->whereIn('tags.id', $tags);
.

업데이트 2 : 이것은 내가 원하는 것을 어떻게 작동시키는 것처럼 보이지만 어떤 이유로, 조직 이름 대신 태그의 이름을 검색합니다 ...

$tags = Input::get('tags');
$query
    ->join('taggables', 'taggables.taggable_id', '=', 'org.id')
    ->where('taggables.taggable_type', '=', 'Org')
    ->join('tags', 'taggables.tag_id', '=', 'tags.id')
    ->groupBy('org.id');

foreach ($tags as $tag)
{
    $query->orWhere('tags.id', '=', $tag);
}
.

도움이 되었습니까?

해결책

다음과 같은 방법으로 키워드 + 태그 검색을 얻었습니다.

$query = Org::query();

// Search by keyword(s)
if(Input::get('keyword'))
{
    $search = Input::get('keyword');
    $searchTerms = explode(' ', $search);
    $fields = array('org.name', 'org.description', 'org.additional_info', 'org.website');

    foreach ($searchTerms as $term)
    {
        foreach ($fields as $field)
        {
            $query->orWhere($field, 'LIKE', '%'. $term .'%');
        }
    }
}

// Search for tag(s)
if(Input::get('tags'))
{
    $tags = Input::get('tags');
    $query
        ->join('taggables', 'taggables.taggable_id', '=', 'org.id')
        ->where('taggables.taggable_type', '=', 'Org')
        ->whereIn('taggables.tag_id', $tags)
        ->groupBy('org.id')
        ->orderBy(DB::raw('count(*)'), 'desc')
        ->orderBy('name', 'asc');
}

$org = $query->get();
.

키워드와 두 개의 태그가 검색에 대해 입력되면 하나 이상의 태그가 하나 이상의 태그가있는 조직을 반환하고 입력 된 키워드와 같은 단어가 포함되어 있으며 조직이가장 일치하는 태그가 먼저 나타납니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top