【问题标题】:advanced search query laravel高级搜索查询 laravel
【发布时间】:2018-10-21 04:06:04
【问题描述】:

在我的网站中,我需要提供一个搜索选项,用户可以在其中搜索不同的产品。现在我想如果搜索键与产品匹配显示它,并显示一些建议包含与该搜索关键字以空格分隔。

list($type,$search) = explode(":", $key);
$searchValues = preg_split('/\s+/', $search, -1, PREG_SPLIT_NO_EMPTY);

ProductDetail::join('product_brands','product_details.brand_id','product_brands.id')
              ->select('brand_name as manufacturer','product_availability as isInStock','product_details.*','product_price as displayPrice')
              ->where(function ($q) use ($searchValues,$search) {
                    $q->where('product_name', 'like', "%{$search}%");
                    foreach ($searchValues as $value) {
                      $q->orWhere('product_name', 'like', "%{$value}%");
                    }
                })->paginate(5);

现在这个结果的问题是,它没有根据最佳/第一匹配显示。因此用户无法在其他建议列表中找到他们正在寻找的内容。

那么如何得到最匹配的订单呢?

View Live Demo

【问题讨论】:

    标签: sql laravel search laravel-5


    【解决方案1】:

    您需要的是某种加权搜索。如果你看一下这个包,你会看到它生成的一些示例 MySQL 查询:https://github.com/nicolaslopezj/searchable

    滚动到“结果”部分,它会显示它生成的查询结果。这将帮助您根据最佳匹配来衡量结果。如果您有更深入的搜索需求,也可以查看Laravel Scout

    这是我所指的示例查询,该包用于搜索 Sed neque labore 之类的用户:

    select `users`.*, 
    
    -- If third parameter is set as true, it will check if the column starts with the search
    -- if then it adds relevance * 30
    -- this ensures that relevant results will be at top
    (case when first_name LIKE 'Sed neque labore%' then 300 else 0 end) + 
    
    -- For each column you specify makes 3 "ifs" containing 
    -- each word of the search input and adds relevace to 
    -- the row
    
    -- The first checks if the column is equal to the word,
    -- if then it adds relevance * 15
    (case when first_name LIKE 'Sed' || first_name LIKE 'neque' || first_name LIKE 'labore' then 150 else 0 end) + 
    
    -- The second checks if the column starts with the word,
    -- if then it adds relevance * 5
    (case when first_name LIKE 'Sed%' || first_name LIKE 'neque%' || first_name LIKE 'labore%' then 50 else 0 end) + 
    
    -- The third checks if the column contains the word, 
    -- if then it adds relevance * 1
    (case when first_name LIKE '%Sed%' || first_name LIKE '%neque%' || first_name LIKE '%labore%' then 10 else 0 end) + 
    
    -- Repeats with each column
    (case when last_name LIKE 'Sed' || last_name LIKE 'neque' || last_name LIKE 'labore' then 150 else 0 end) + 
    (case when last_name LIKE 'Sed%' || last_name LIKE 'neque%' || last_name LIKE 'labore%' then 50 else 0 end) +
    (case when last_name LIKE '%Sed%' || last_name LIKE '%neque%' || last_name LIKE '%labore%' then 10 else 0 end) + 
    
    (case when bio LIKE 'Sed' || bio LIKE 'neque' || bio LIKE 'labore' then 30 else 0 end) + 
    (case when bio LIKE 'Sed%' || bio LIKE 'neque%' || bio LIKE 'labore%' then 10 else 0 end) + 
    (case when bio LIKE '%Sed%' || bio LIKE '%neque%' || bio LIKE '%labore%' then 2 else 0 end) + 
    
    (case when email LIKE 'Sed' || email LIKE 'neque' || email LIKE 'labore' then 75 else 0 end) + 
    (case when email LIKE 'Sed%' || email LIKE 'neque%' || email LIKE 'labore%' then 25 else 0 end) + 
    (case when email LIKE '%Sed%' || email LIKE '%neque%' || email LIKE '%labore%' then 5 else 0 end) 
    
    as relevance 
    from `users` 
    group by `id` 
    
    -- Selects only the rows that have more than
    -- the sum of all attributes relevances and divided by 4
    -- Ej: (20 + 5 + 2) / 4 = 6.75
    having relevance > 6.75 
    
    -- Orders the results by relevance
    order by `relevance` desc
    

    【讨论】:

    • 感谢您的帮助。我会尝试实现这个。我真的很喜欢这个包
    猜你喜欢
    • 2015-06-09
    • 1970-01-01
    • 2015-01-14
    • 2018-08-01
    • 1970-01-01
    • 2015-04-17
    • 2016-03-27
    • 2014-06-08
    • 1970-01-01
    相关资源
    最近更新 更多