2013-04-16 28 views
10

Virgülle ayrılmış anahtar kelimeler içeren bir dizim var. Örneğin:MySQL ve PHP: Çoklu Anahtar Kelime Araması

$keywords = 'keyword1, keyword2, keyword3'; 

tbl_address adlı My Tablo şema, bu (basitleştirilmiş) gibidir:

id  INT(11)  PRIMARY KEY, AUTO INCREMENT 
address VARCHAR(250) NOT NULL 

PHP MySQLi (değil PDO) kullanmak zorunda varsayalım.

$result = array(); 
$keyword_tokens = explode(',', $keywords); 
foreach($keyword_tokens as $keyword) { 
    $keyword = mysqli_real_escape_string(trim($keyword)); 
    $sql = "SELECT * FROM tbl_address WHERE address LIKE'%$keyword%'"; 
    // query and collect the result to $result 
    // before inserting to $result, check if the id exists in $result. 
    // if yes, skip. 
} 
return $result; 

Bu yaklaşım çalışır ancak performansında verimsiz:

İşte benim şimdiki yaklaşımdır. Çok fazla anahtar kelime varsa, çok fazla sorgulama yapar.

Sorum şu: Aynı hedefe ulaşmak için daha iyi bir yol var mı? yani, tüm kayıtları anahtar kelimelerin herhangi birini içeren adresle birlikte göndermenin en kolay yolu nedir?

+0

Bu size yardımcı olabilir: http: // stackoverflow.com/a/9736386/1983854 – fedorqui

+0

“LIKE” ve “IN” özelliklerini birleştirin: http://stackoverflow.com/questions/1865353/combining-like-and-in-for-sql-server – Chris

+2

@Shivian Seriously, neden olmasın? REGEXP tek linerimi kullanıyor musunuz? – Jimbo

cevap

17

Basit bir REGEXP sizin için uygun olabilir. Kendiniz için ne kadar verimli olduğunu kontrol etmeniz gerekir.

SELECT * FROM tbl_address WHERE field REGEXP 'keyword1|keyword2|keyword3';

+1

+1, tam da aradığım şey buydu, ayrıca yeni bir 'MySQL' fonksiyonunu da öğrendim! –

+1

Mükemmel cevap, bu bir hafta süren araştırmaları çözmeme yardımcı oldu ve benim sorunumun% 30'unu atlamama yardımcı oldu :) – Birdy

0

En iyi yol, tam metin araması kullanmaktır.

http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html

Kullanmak VEYA NEREDE durumda olabilir tam metin kullanmak istemiyorsanız sadece arama dizesini WHERE yan tümcesi oluşturmak ve sorgulamak ekler edilir

SELECT * FROM tbl_address WHERE address LIKE '%$keyword%' OR adress LIKE '%$keyword2%' 
5
SELECT * FROM user; 
+---------+----------+ 
| user_id | username | 
+---------+----------+ 
|  101 | Adam  | 
|  102 | Ben  | 
|  103 | Charlie | 
|  104 | Dave  | 
+---------+----------+ 

SELECT * 
    FROM user 
    WHERE FIND_IN_SET(username,'adam,ben,dave') > 0; 
+---------+----------+ 
| user_id | username | 
+---------+----------+ 
|  101 | Adam  | 
|  102 | Ben  | 
|  104 | Dave  | 
+---------+----------+ 
+0

Bu yaklaşımla sadece bir çift uyarı. LIKE sözdizimini kullanamazsınız ve anahtar kelimeleri kırpmaz ... – arraintxo

0

iyi yolu ve bir kez çalıştırın.

$result = array(); 
$keyword_tokens = explode(',', $keywords); 
$where = '';$i=0 
foreach($keyword_tokens as $keyword) { 
    $where.= " address LIKE'%".mysqli_real_escape_string(trim($keyword))."%' OR "; 
} 
    // trim last OR with substr_replace 
    substr_replace($where, "OR", -1, 1); 
    $sql = "SELECT * FROM tbl_address WHERE $where"; 

return $result; 
0

Merhaba birliği ile bir sorgu oluşturmak ve burada sorguyu yürütün döngü

$result = array(); 
$keyword_tokens = explode(',', $keywords); 
$sql = ''; 
foreach($keyword_tokens as $keyword) { 
    $keyword = mysqli_real_escape_string(trim($keyword)); 
    if (!empty($sql)) $sql .= " UNION "; 
    $sql .= "SELECT * FROM tbl_address WHERE address LIKE'%$keyword%'"; 
    // query and collect the result to $result 
    // before inserting to $result, check if the id exists in $result. 
    // if yes, skip. 
} 

sonunda yürütün.

3

Yalnızca bir 'OR', başka bir şey ...

<?php 

$result = array(); 
$keyword_tokens = explode(',', $keywords); 
$keyword_tokens = array_map('mysqli_real_escape_string', $keyword_tokens); 

$sql = "SELECT * FROM tbl_address WHERE address LIKE'%"; 
$sql .= implode("%' or address LIKE '%", $keyword_tokens) . "'"; 

// query and collect the result to $result 
// before inserting to $result, check if the id exists in $result. 
// if yes, skip. 

return $result; 

düzenlemek gerekir: Sadece ayrıca

<?php 

$result = array(); 
$keyword_tokens = explode(',', $keywords); 
$keyword_tokens = array_map(
    function($keyword) { 
     return mysqli_real_escape_string(trim($keyword)); 
    }, 
    $keyword_tokens 
); 

$sql = "SELECT * FROM tbl_address WHERE address LIKE'%"; 
$sql .= implode("%' OR address LIKE '%", $keyword_tokens) . "'"; 

// query and collect the result to $result 
// before inserting to $result, check if the id exists in $result. 
// if yes, skip. 

return $result; 

Ayrıca anahtar kelimeleri Döşeme emin olmak için, ayrıca geçirmesi gerektiğini mysqli_real_escape_string() işlevine db kaynak bağlantısı ...

+0

Eğer '$ sql' için sondaki tek bir alıntıyı kaçırdınız. – Raptor

+1

Haklısınız. Hepsi çok eklendi :) – arraintxo

+0

Bu çalışmıyor; sql hatası olduğunu söylüyor; – Eenvincible

1

Tek bir sorgu oluştur

$keywordary = explode(',', $keywords); 
foreach($keywordary as $keyword) { 
    $keys = trim($keyword); 
    $other .=" or address like '%$keys%'"; 
} 
$sql = "SELECT * FROM tbl_address WHERE address LIKE'%$keyword%' $other"; 

execute query; 
return $result; 
+1

Bu, "$ other =" 'yerine başka bir şey değil. Aksi halde, her döngüde 'ya da 'maddesini iptal edersiniz. – TheCarver

1

deneyin NEREDE yan tümcesi:

$keyword = (array)explode(',', $keywords); 
for($i=0;$i=count($keyword);$i++){ 
    $keyword[$i]=mysqli_real_escape_string(trim($keyword[$i]),'\'" '); 
} 
//This is what I suggest. 
$query='SELECT * FROM tbl_address WHERE address IN ("'.implode('","',$keyword).'")'; 

Başarıyla MySQL 5.1 üzerinde test.