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

s4chpxco  于 2022-12-31  发布在  Android
关注(0)|答案(4)|浏览(147)

我曾尝试使用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甚至assan,查询不应该显示这个字符串。这意味着如果搜索,它必须使用startwith进行搜索,而不是从中间搜索。我认为如果我从开始删除%,可能会有这种可能。但问题是查询将只看到Syed上的startwith,我希望它应用startwith对每个单词,因为单词是由空格分隔的。搜索SyedHaiderHassan不同。
但简单地说,如果你有Android Mobile,我有Galaxy S4,搜索你的通讯录中的任何名字。如果你从单词中间搜索,它不会搜索,但如果你从单词开始搜索,它会搜索,但这只是不是它。如果你的联系人姓名是由空格分隔的两个单词的组合,那么它也会检查第二个单词的第一个字母。
如何将查询更新为新的搜索条件?

更新

我尝试了匹配对中建议的答案之一使用try catch,我得到这个错误:

下面是我尝试的代码:

$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();
        }

我该怎么解决呢?

更新2

我把事实简单地放在这里。下面是我的表格结构:

如果我使用通配符%%的like,它将从名称中间搜索偶数。
让我们看看屏幕截图中突出显示的名称,突出显示的名称是Lukasz Henryk
如果我使用通配符搜索像% enry %,它会找到我此行。但我不想这样,我想搜索应该与名称开始字。例如,如果我搜索LukHenHe或甚至H,它应该找到我此行。这意味着开始字母表是重要的,如果开始字母表不匹配,然后不给我行。
我还尝试了一个通配符查询,如Henr%,但它不工作,因为这样它只适用于Luk%,它认为整个列作为一个字符串。
有没有一种方法可以让查询在空格后搜索起始字母表?

4nkexdtk

4nkexdtk1#

正如其他人所说,全文索引是要走的路这是你希望你的查询看起来像,+使所有需要的单词离开它查找任何单词。你不能使用"双引号,与*通配符,这是合理的,因为双引号意味着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

uwopmtnx

uwopmtnx2#

你可以使用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)
lndjwyie

lndjwyie3#

你有没有试过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
tktrz96b

tktrz96b4#

您的问题来自搜索字符串($search_words =“+”. str_replace(““,“* +",$searchFilter)."*";),因为关系运算符是“+,-,〈〉等,"这就是为什么你需要先看到你的完整查询。
执行以下步骤:
1.回显您的SQL查询,并尝试在一些MySql GUI(如Navicat)中执行,以确保您的查询没有错误。
1.请确保客人名字、客人姓名字段索引为“全文”。为此,您需要执行“更改表RESERVATION_GENERAL_2添加全文索引name_indexGUEST_FIRST_NAMEGUEST_NAME);“
试试这个步骤,然后告诉我。

相关问题