2017-08-08 83 views
2

我想搜索一個數據庫列varchar所有由空格分隔的字符串排列。例如:Mysql搜索所有字符串排列

search: foo 
matches: foo, foo bar, bar foo 

search: foo bar 
matches: foo bar, bar foo, bar foo green, green foo bar 

我使用PHP和PDO來生成搜索。創建和搜索包含許多單詞的字符串時,我遇到了速度問題,因爲有很多可能的排列組合在查詢中創建和包含。下面是我用來生成排列的PHP代碼。也許有一種方法可以減少術語數量?

function permutations($set) { 
    $solutions = array($set); 
    $n = count($set); 
    $p = array_keys($set); 
    $i = 1; 
    while ($i < $n) { 
     if ($p[$i] > 0) { 
      $p[$i]--; 
      $j = 0; 
      if ($i % 2 == 1) 
       $j = $p[$i]; 
      //swap 
      $tmp = $set[$j]; 
      $set[$j] = $set[$i]; 
      $set[$i] = $tmp; 
      $i = 1; 
      $solutions[] = $set; 
     } 
     elseif($p[$i] == 0) { 
      $p[$i] = $i; 
      $i++; 
     } 
    } 
    return $solutions; 
} 

回答

0

在我看來,你的邏輯,等於只檢查一個或多個關鍵字存在於數據庫列,在串/句子的任何地方。如果是這樣,那麼,以下類型的查詢可能對你是足夠的:

SELECT * 
FROM yourTable 
WHERE 
    column LIKE CONCAT('%', 'foo', '%') AND 
    column LIKE CONCAT('%', 'bar', '%') 

如果你打算做這樣的大量工作,它可能是值得的,同時投資一些瞭解MySQL的全文搜索功能。如果你對你的表全文索引,那麼類似下面的查詢也將接近你心目中:

SELECT * 
FROM yourTable 
WHERE MATCH(column) AGAINST('foo,bar') 
+0

不完全。也許我沒有在我的問題中表達得很好,但如果搜索詞有兩個單詞,我希望他們兩個都在答案中。 –

+0

@JohnCarroll我的查詢符合此要求。你有麻煩去測試它嗎?我檢查是否存在每個搜索項,並且只有當所有項都存在時纔會返回記錄。 –

+0

不,我沒有測試,我讀了解釋,並認爲它接近但不匹配。我現在會測試。 –

0

我用我的功能在我的項目: 此功能chesk做$列類似於$什麼?

例如:

student = smith 
what= mike smith 
result:YES 

https://3v4l.org/eUOS1

,並反向太:

student =mikesmith 
what= smith 
result:YES 

function TRIM_SEARCH_TABLE_UNIQ($column,$what) 
{ 
$Find=0; 

    $e1=strpos('0'.trim(strtolower($column)),trim(strtolower($what))); 
    $e2=strpos('0'.trim(($what)),trim(strtolower($column))); 
    if(($e1>0)||($e2>0)) 
     { 
      $Find=1; 
      return "YES"; 
     } 

return "NO"; 
} 
+0

這是一個方便的功能,但是我想在查詢時執行搜索。否則,我將不得不拉動所有行(ALOT),然後執行此功能。 –

0

您可以嘗試MATCH AGAINST一個字符串的所有排列。例如:

SELECT * FROM table WHERE MATCH(column) AGAINST ('foo bar'); 

比賽:FOO酒吧,酒吧FOO,FOO條綠,綠壩富,富綠吧,酒吧綠富,富,酒吧


但是,對於你的要求,你可以做一些修正,它在你的搜索字符串的所有單詞添加+操作:

$search_string = "foo bar"; 
$search_string = "+". str_replace(' ', " +", $search_string); 

和運行這樣的SQL:

SELECT * FROM table WHERE MATCH(column) AGAINST ('$search_string' IN BOOLEAN MODE); 

比賽:FOO酒吧,酒吧FOO,FOO條綠,綠壩富,富綠吧,酒吧綠富


記得在立柱結構添加全文索引:

ALTER TABLE table ADD FULLTEXT (column); 

全文檢索參考:link

+0

這是最接近我到目前爲止所尋找的。我不知道MATCH/AGAINST。謝謝你給我看!唯一的問題是我不希望'foo bar'匹配'foo'或'bar'。我希望它匹配'foo bar','bar foo','bar foo green',... –

+0

我已經編輯了答案,希望它有所幫助:) –

+0

令人驚歎 - 我會好奇的看看這個測試的速度明智地對抗Tim的答案 –