【问题标题】:Laravel Eloquent / SQL - search for keywords in dbLaravel Eloquent / SQL - 在数据库中搜索关键字
【发布时间】:2017-02-05 13:58:52
【问题描述】:

我目前正在尝试在我的数据库中搜索关键字/标签。

在我的数据库中,我的行包含以下关键字: auto,cabrio,frischlufthose,jeans,blaue hose,kleidung

所以总是有一些关键字(基本上也可以有空格),用逗号分隔(,)。

现在我希望能够在我的数据库中找到输入了一些关键字的产品。

使用LIKE,我可以找到我在auto,cabriocabrio,frischlufthose,jeans,blauhose,kleidung 等查询中提到的两个条目。但是如果我输入auto,frischluft 或类似hose,blaue hosejeans,kleidung 会发生什么?

然后LIKE 将不再工作。有没有办法做到这一点?

我希望你明白我的意思......

所以要明确一点:我目前使用的代码是: $searchQuery = "%".$request->input('productSearch')."%"; $products = Product::where('name', 'LIKE', $searchQuery)->paginate(15);

但正如我所说,如果输入 productSearch 输入了关键字 auto,frischluft,这不会让我回到关键字 auto,cabrio,frischluft 的文章...

有什么想法吗?

【问题讨论】:

    标签: php mysql sql laravel eloquent


    【解决方案1】:

    抱歉,我知道我参加聚会迟到了,但这是我在 Google 中寻找 Eloquent 关键字搜索时的第一个结果。我遇到了同样的问题,我想帮助解决我的问题。

    $q = $request->input('productSearch');
    $needles = explode(',', $q);
    
    // In my case, I wanted to split the string when a comma or a whitespace is found:
    // $needles = preg_split('/[\s,]+/', $q);
    
    $products = Products::where('name', 'LIKE', "%{$q}%");
    
    foreach ($needles as $needle) {
        $products = $products->orWhere('name', 'LIKE', "%{$needle}%");
    }
    
    $products = $products->paginate(15);
    

    如果用户输入的逗号太多,$needles 数组可能太大(并且查询太大),因此您可以限制搜索,例如,仅搜索数组中的前 5 个元素:

    $needles = array_slice($needles, 0, 5);
    

    我希望这可以帮助某人。

    【讨论】:

      【解决方案2】:

      关于你刚才的回复:

      如果您想要更简单,请阅读此 MySQL 文档:https://dev.mysql.com/doc/refman/5.7/en/regexp.html

      基本上,您可以在一个文件中通过grep 查找[,]?blaue hose[,]?:一个可选的逗号、字符串“蓝色软管”和一个可选的逗号。

      我最初的答案是更可靠的解决方案:

      您实际上可以创建一个关键字表,具体取决于您的 products 表,其中每个关键字/关键字 单独在一列中,甚至在关键字/关键字上放置一个索引。我这里解释一下原理:

      Optimising LIKE expressions that start with wildcards

      并且,以您​​的示例作为输入 - 这是我在 Vertica 中的操作方式。许多数据库提供返回的函数 由您选择的字符分隔的字符串的第 n 个部分/标记。在 Vertica 中,它是 SPLIT_PART()。

      不幸的是,MySQL 不提供与该函数的任何对应关系,您必须将以下 WITH 子句中的公用表表达式转换为内联 SELECT-s (SELECT ... FROM (SELECT ... ) AS foo(col1,col2,col3) ....。然后,有一个建议这里来自 Daniel Vassallo 关于如何解决它:

      Split value from one field to two

      在 Vertica 中,它看起来像这样:

      WITH 
      -- input
      products(prod_id,keywords) AS (
                SELECT 1001,'auto,cabrio,frischluft'
      UNION ALL SELECT 1002,'hose,jeans,blaue hose,kleidung'
      )
      ,
      -- index to get the n-th part of the comma delimited string
      max_keyword_count(idx) AS (
                SELECT 1
      UNION ALL SELECT 2
      UNION ALL SELECT 3
      UNION ALL SELECT 4
      UNION ALL SELECT 5
      )
      SELECT
        prod_id
      , idx
      , TRIM(SPLIT_PART(keywords,',',idx)) AS keywords
      FROM products
      CROSS JOIN max_keyword_count
      WHERE SPLIT_PART(keywords,',',idx) <> ''
      ORDER BY
        prod_id
      , idx
      ;
      
      prod_id|idx|keywords
        1,001|  1|auto
        1,001|  2|cabrio
        1,001|  3|frischluft
        1,002|  1|hose
        1,002|  2|jeans
        1,002|  3|blaue hose
        1,002|  4|kleidung
      

      【讨论】:

      • 谢谢你的回答,但这听起来很难。有没有更简单的方法可以做到这一点?
      • 在这种情况下,请阅读此 MySQL 文档:dev.mysql.com/doc/refman/5.7/en/regexp.html。基本上,在一个文件中,您可以通过grep 找到[,]?blaue hose[,]?:一个可选的逗号、字符串“蓝色软管”和一个可选的逗号。
      • 但这基本上也是LIKE 会做的,不是吗?因为在使用hose,blaue hose 时我怎么能使用你的想法?应以关键字hose,jeans,blaue hose,kleidung 结尾
      • 如果您的意思是您提供一个关键字列表作为输入,并且如果您在“hose,jacke,jeans,blue软管”中搜索“软管,蓝色软管”,希望找到匹配项- 那么这不是你可以问的 SQL 问题。您必须以编程方式将搜索条件转换为 WHERE keywords LIKE '%hose% OR keywords LIKE '%blaue hose%'
      • 好吧,你可能是对的,但如果我像你现在建议的那样使用 OR,我会在这个问题中运行,也会有只包含 hoseblaue hose 的结果,但不是两者都在一起。但我想你明白我的想法。我有一个带有关键字列表的产品,然后我希望能够将关键字列表传递给搜索字段,并且我想找到包含从搜索框中传递的所有关键字的产品,无论它们是什么顺序为产品保存
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-02
      • 1970-01-01
      • 2019-08-13
      • 2015-06-19
      相关资源
      最近更新 更多