【问题标题】:mysql like to match complete word or beginning of word on stringmysql喜欢匹配字符串上的完整单词或单词的开头
【发布时间】:2013-10-31 22:31:51
【问题描述】:

给定一个搜索字符串,我需要选择每条记录,其中(在执行搜索的字段中)至少有一个以给定文本开头的单词。

例如:

'John Doe'

必须使用搜索字符串选择,例如:

'joh'
'do'
'JOHN doe'

被选中

'ohn'
'oe'

我需要(可能)避免全文搜索。

我发现工作是

$query = 'SELECT * FROM MYTABLE WHERE SEARCHFIELD LIKE "' . $searchText . '%"'
                                . 'OR SEARCHFIELD LIKE "% ' . $searchText . '%"'

我在问是否有更好的方法来做到这一点。

(对于“更好的方式”,我的意思是更好的性能相同的性能但更优雅

另外,由于查询将使用准备好的语句构建,我应该如何在搜索字符串中取消 LIKE 元字符?

【问题讨论】:

    标签: mysql sql-like


    【解决方案1】:

    正如问题中已经说明的查询

    $query = 'SELECT * FROM MYTABLE WHERE SEARCHFIELD LIKE "' . $searchText . '%"'
                                    . 'OR SEARCHFIELD LIKE "% ' . $searchText . '%"'
    

    适用于匹配SEARCHFIELD 包含以$searchText 开头(或等于)的单词的记录


    关于性能我在我的开发机器上做了一个测试MBP 2,2 GHz i7 quad core:

    在 4000 条记录上搜索一个单词大约需要 40 毫秒。

    记录通常有索引(没有全文)。

    我有几千条记录,查询不经常运行,所以对我来说很好。
    该解决方案可能不适用于其他环境。


    为了使用上述查询构建一个准备好的语句,我使用了这里描述的技术:

    Escaping MySQL wild cards

    生成的代码如下:

    function like($s, $e)
    {
        return str_replace(array($e, '_', '%'), array($e . $e, $e . '_', $e . '%'), $s);
    }
    
    /* ... */
    
    /* create a prepared statement */
    $stmt = $mysqli->prepare(
        'SELECT * FROM MYTABLE WHERE SEARCHFIELD LIKE ? ESCAPE "=" OR SEARCHFIELD LIKE ? ESCAPE "="'
    ); 
    
    if( $stmt )
    {
        /* escape the text */
        $escSearchText = like( $searchText, "=" );
    
        /* 'like' parameters */
        $like1 = $escSearchText . "%";
        $like2 = "%" . $escSearchText . "%";
    
        /* bind parameters for markers */
        $stmt->bind_param( "ss", $like1, $like2 );
    
    /* ... */
    

    【讨论】:

      【解决方案2】:

      使用这个:

      $query = "SELECT * FROM MyTable WHERE searchfield LIKE CONCAT('%', ?, '%')";
      

      您不需要OR 条件——如果一个字段匹配search%,它也将匹配%search%

      【讨论】:

      • 不,它也会与 'oe' 或 'ohn' 匹配。我将编辑我的问题以明确这一点
      • LIKE 不能进行单词匹配,只能匹配字符串。
      • 您需要使用RLIKE 而不是LIKE 并创建一个正则表达式。相同的基本方法仍然有效,您只需使用匹配单词开头的正则表达式而不是第一个 %
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-24
      • 1970-01-01
      • 2010-12-15
      • 1970-01-01
      相关资源
      最近更新 更多