PDO搜索查询,使其像android联系人搜索

时间:2014-09-10 09:04:43

标签: php android sql search pdo

我尝试使用LIKE查询在我的小工具中实施搜索。

现在我有了这个新要求,我必须像Android搜索一样进行搜索..

查询:

$stmt = $conn->prepare("SELECT ROOM, GUEST_NAME, GUEST_FIRST_NAME, CONFIRMATION_NO, DEPARTURE, PWD FROM RESERVATION_GENERAL_2 WHERE LOWER(GUEST_FIRST_NAME) LIKE ? OR LOWER(GUEST_NAME) LIKE ?");
$stmt->execute(array('%'.strtolower($searchFilter).'%','%'.strtolower($searchFilter).'%' ));

假设我在数据库中有一个字符串Syed Haider Hassan 如果我使用给定的查询在数据库表中搜索san,它会在上面的字符串中找到我。 因此,如果我把任何匹配在字符串内部或任何地方匹配,它将得到我这个字符串,

但我想要的是,当我在数据库HaiHasSy中搜索时,它应该为我提供此字符串,但如果我搜索san或甚至{ {1}},查询不应该显示此字符串。 意味着如果我搜索它必须用assan搜索,而不是从中间搜索。 我认为如果我从开始删除startwith可能是可能的,但问题是查询只会在Syed上看到startwith,我希望它在每个单词上应用startwith,因为单词是由空格分隔的。不同地搜索% Syed Haider ..

我知道上面我试图解释的是非常令人困惑的,主要是因为我的英语不好。 但简单来说,如果你有Android手机,我有Galaxy S4,搜索你的通讯录中的任何名字。如果你从单词的中间搜索它将不会搜索,但如果你从单词的开头搜索它将搜索,但那不是它。如果您的联系人姓名是由空格分隔的两个单词的组合 然后它还会检查第二个单词的第一个字母。

我希望我很清楚,但我不知道如何实现该查询。如果有人可以将我的查询更新为这个新的搜索条件,我将非常高兴。

=======================================

更新

好吧,我尝试了使用try catch的回答中建议的匹配,我得到了这个错误。 enter image description here

这是我试过的代码。

Hassan

任何想法如何解决?

===================================

更新2

好的,我只是把事实放在这里。 这是我的表格结构。 enter image description here

如果我喜欢使用通配符%%,它甚至会从名称中间搜索。

让我们在屏幕截图中看到突出显示的名称,突出显示的名称为$search_words = "+" . str_replace (" ", "* +", $searchFilter )."*"; try { $stmt = $conn->prepare("SELECT ROOM, GUEST_NAME, GUEST_FIRST_NAME, CONFIRMATION_NO, DEPARTURE, PWD FROM RESERVATION_GENERAL_2 WHERE MATCH (GUEST_FIRST_NAME, GUEST_NAME) against (:SEARCH in boolean mode)"); $stmt->bindValue(':SEARCH', $search_words, PDO::PARAM_STR); $stmt->execute(); } catch(PDOException $e){ echo 'ERROR: ' . $e->getMessage(); } 。 如果我使用%enry%搜索外卡,它会找到我这一行。 但我不想要那个,我希望搜索应该用名字开头。 e-g如果我搜索Lukasz HenrykLukHen或甚至He,它应该会找到我这一行。意味着开始字母表很重要,如果开始字母表不匹配,那么就不要给我这一行。

我也尝试了像H这样的通配符,但它不起作用,因为它只适用于Henr%,它将整列视为单个字符串。

是否有办法告诉查询在空格后搜索起始字母?

请有人帮帮我。

4 个答案:

答案 0 :(得分:1)

正如其他人所说,全文索引是要走的路,这就是你希望你的查询看起来的样子,+使所有需要的单词留下来查找任何单词。您不能使用"双引号和*通配符,这是合理的,因为双引号表示exact个单词。使用外卡时不能使用它。 (或者至少我还没有办法做到这一点)

SELECT
    ROOM,
    GUEST_NAME,
    GUEST_FIRST_NAME,
    CONFIRMATION_NO,
    DEPARTURE,
    PWD
FROM
    RESERVATION_GENERAL_2
WHERE
    MATCH(GUEST_NAME, GUEST_FIRST_NAME)
AGAINST
    ( '+word* +word2*' IN BOOLEAN MODE )

基本上

  $search_words = '';
 foreach( explode(' ', $search) as $words ){
       $search_words .= '+'.$word.'* ';
 }

...
WHERE
    MATCH(GUEST_NAME, GUEST_FIRST_NAME)
AGAINST
    ( :search_words IN BOOLEAN MODE )

 $stmt->bindValue(':search_words', $search_words, PDO::PARAM_STR);

等等...

但你必须有一个全文索引,在这种情况下是GUEST_NAME, GUEST_FIRST_NAME上的复合索引。

另见

MySQL Full Text Search Mystery

答案 1 :(得分:0)

你可以使用MySQL:s MATCH AGAINST。请记住,您必须制作包含GUEST_FIRST_NAME和GUEST_NAME的FULLTEXT索引(按此顺序)。

只是一个例子:

$string = "syed haider";
$search_words = "+" . str_replace (" ", "* +", $string )."*";

$query = "SELECT ROOM, GUEST_NAME, GUEST_FIRST_NAME, CONFIRMATION_NO, DEPARTURE, PWD FROM RESERVATION_GENERAL_2 WHERE MATCH (GUEST_FIRST_NAME) against ('$search_words' in boolean mode) OR MATCH (GUEST_NAME) against ('$search_words' in boolean mode)";

// SELECT ROOM, GUEST_NAME, GUEST_FIRST_NAME, CONFIRMATION_NO, DEPARTURE, PWD FROM RESERVATION_GENERAL_2 WHERE MATCH (GUEST_FIRST_NAME) against ('+syed* +haider*' in boolean mode) OR MATCH (GUEST_NAME) against ('+syed* +haider*' in boolean mode)

答案 2 :(得分:0)

你试过mysql regexp(rlike)吗?

表格设置:

CREATE TABLE `user` (
  `name` varchar(50) NOT NULL DEFAULT ''
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `user` (`name`)
VALUES
    ('Syed Haider Hassan');

查询:

select * from user where name rlike '[[:<:]]Hass'

返回:

name
Syed Haider Hassan

不匹配查询:

select * from user where name rlike '[[:<:]]san'

返回:

name

答案 3 :(得分:0)

您的问题来自搜索字符串($ search_words =“+”。str_replace(“”,“* +”,$ searchFilter)。“*”;),因为关系运算符是“+, - ,&lt;&gt;等等“,这就是为什么你需要先看到你的完整查询。

采取以下步骤:

  1. 回显您的sql查询并尝试在某些MySql GUI(例如Navicat)中执行,以确保您的查询没有错误。
  2. 确保GUEST_FIRST_NAME,GUEST_NAME字段索引为“全文”。为此你需要执行“ALTER TABLE RESERVATION_GENERAL_2 添加FULLTEXT索引name_indexGUEST_FIRST_NAMEGUEST_NAME);“
  3. 尝试以下步骤告诉我们。