Search scope for multiple columns of data in Laravel Model

泄露秘密 提交于 2020-01-25 10:31:08

问题


I have a Model within Laravel called Blah (I named it this way because you can't simply name a class Class, so I changed the name temporarily).

Within the classes table, each row contains data like this:

   {
       year: "2015",
       term: "Summer",
       subject_code: "DIGM",
       course_no: "350",
       instr_type: "Lecture",
       instr_method: "Face To Face",
       section: "003",
       crn: "42953",
       course_title: "Digital Storytelling",
       credits: "3.0",
       day: "R",
       time: "06:30 pm - 09:20 pm",
       instructor: "Teacher Name",
       campus: "University Building",
       max_enroll: "18",
       enroll: "18",
       building: "PLACE",
       room: null,
       description: "By surfing the internet and playing computer games, by lectures, assigned readings, class screening, and research projects, this class explores the impact of digital media on art, design and daily living. This is a writing intensive course. ",
       pre_reqs: "",
       co_reqs: ""
   }

I developed a scope search query within my Blah Model like so:

/**
 * Search scope query
 *
 * @param string
 * @return QueryBuilder
 */
public function scopeSearch($query, $searchTerm) {
    return $query
        ->where('course_title', 'like', "%" . $searchTerm . "%");
}

The above scope search would allow me to search for the term digital and it would return the class called Digital Storytelling.

However, I would like to take it further - I would like to be able to, in the same search scope, perform a search like DIGM 350 (these two data points are from subject_code and course_no) and it would bring up the same result.

So, searching DIGM 350 and/or digital would bring up the same result. This would be part of my site's auto-search box.

Final Query:

/**
 * Search for course title or subject name
 * @param $query
 * @param $searchTerm Course Title or Subject Name
 * @return mixed
 */
public function scopeSearch($query, $searchTerm) {
    return $query
        ->where('course_title', 'like', '%' . $searchTerm . '%')
        ->orWhere(DB::raw("subject_code || ' ' ||  course_no"),
            'like',
            '%' . $searchTerm . '%'
        )
        ;
}

Thanks Ian.


回答1:


You could use the orWhere() method of the query builder to do something similar to your example:

    public function scopeSearch($query, $searchTerm) {
        return $query
            ->where('course_title', 'like', "%" . $searchTerm . "%")
            ->orWhere('subject_code', 'like', "%" . $searchTerm . "%")
            ->orWhere('course_no', 'like', "%" . $searchTerm . "%");
    }

However, the real problem here is that MySQL "like" queries may not be powerful enough to do what you're trying to do, since neither the subject_code or course_no columns contain the string "DIGM 350". You could do a like query on the concatination of those columns that would look something like this:

    public function scopeSearch($query, $searchTerm) {
        return $query
            ->where('course_title', 'like', "%" . $searchTerm . "%")
            ->orWhere(DB::raw("CONCAT_WS(' ',subject_code,course_no)"), 'like', "%" . $searchTerm . "%");
    }

That would do a like query matching any rows where the value of subject_code and course_no separated by a space contains the search string (or if the course_title contains it).

I think your needs may warrant an actual search engine, though.



来源:https://stackoverflow.com/questions/31416476/search-scope-for-multiple-columns-of-data-in-laravel-model

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!