简体   繁体   中英

How to prioritize result in laravel eloquent

I have a table with 4 columns. I want to display the row based on input and it should be able to display with priority according to the priority fields.

example: My table looks like this:

ID  title          description    tags
1   web developer  designer       front-end
2   designer       front-end      web developer
3   front-end      web developer  designer

I have my test cases below how it should work:

$input = 'web developer' // the sequence should be IDs : 1, 3, 2
$input = 'front-end'     // output sequence result is : 3, 2, 1
$input = 'designer'      // result sequence : 2, 1, 3

Now, I want to prioritize the result from title down to tags based in the input.

$blog = DB::('blogs')
        ->where('title', 'LIKE', '%$title%')
        ->where('description', 'LIKE', '%$title%')
        ->where('tags', 'LIKE', '%$title%');

But the above codes, seems that it didn't..

I think the logic you want to order your result should be appearing in an ORDER BY clause. Consider the following raw query:

SELECT *
FROM yourTable
ORDER BY
    CASE WHEN title = 'web developer'       THEN 0 ELSE 1 END,
    CASE WHEN description = 'web developer' THEN 0 ELSE 1 END,
    CASE WHEN tags = 'web developer'        THEN 0 ELSE 1 END;

Output:

显示排序结果的图像

Here is my attempt at what the Laravel code would look like using orderByRaw :

$orderByClause  = "CASE WHEN title = '".$input."' THEN 0 ELSE 1 END,";
$orderByClause .= "CASE WHEN description = '".$input."' THEN 0 ELSE 1 END,";
$orderByClause .= "CASE WHEN tags = '".$input."' THEN 0 ELSE 1 END";

$blog = DB::('blogs')
        ->orderByRaw($orderByClause)
        ->get();

I couldn't find any (working) documentation on how to parameterize an orderByRaw , so I used string concatenation instead.

Demo here:

Rextester

Not a good solution but this might help you,

$input = 'web developer';

$byTitle = DB::('blogs')
           ->where('title', 'LIKE', '%$input%')
           ->select('id');

$byDescription = DB::('blogs')
                 ->where('description', 'LIKE', '%$input%')
                 ->select('id');

$byTag = DB::('blogs')
         ->where('tag', 'LIKE', '%$input%')
         ->select('id');

$ids = $byTitle->union($byDescription)->union($byTag)->get();

You can select id according to column and then union of them to get data.

Here is what a raw query would look like if you wanted to handle this via a UNION :

SELECT ID, 1 AS priority
FROM blogs
WHERE title = 'web developer'
UNION
SELECT ID, 2
FROM blogs
WHERE description = 'web developer'
UNION
SELECT ID, 3
FROM blogs
WHERE tags = 'web developer'
ORDER BY
    priority,
    ID

One caveat here is that if a given record had the same value for two or more of the title, description, or tags columns, then you would end up with duplicate records appearing in the result set. From your original data, this does not appear to be happening, though this is an edge case worth mentioning.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM