在PHP中创建搜索功能

时间:2018-10-25 09:25:21

标签: php search

TL; DR

如何根据爆炸的$_POST['search']过滤大型数组以匹配数据库中的搜索词?

全副武装

我正在尝试构建一种搜索算法,但我似乎陷入了一个字以上的术语。

其背后的逻辑(或我正在尝试实现的逻辑)是

我有7个要检查的字段:

  

制作
  型号
  杂项名称
  街道名称
  ID
  CC
  年

当用户仅键入一个搜索词时,它将检查这些字段,然后过滤出重复项并返回结果。我到此为止,然后尝试实现“更严格的搜索”,如果用户键入“ Honda XL”之类的内容,则只应返回行中包含Honda和XL的结果。

我认为我可以使用array_diffarray_filter来实现这一目标(也许我可以,只是不能正确使用它),但是结果仍然会显示带有不包含XL的字词

这是我脚本的重要部分:

1)单个字段搜索:

if (is_numeric($search)) {
    foreach ($numericFields as $key => $field)
    {
        $res = $handler->prepare($sql. '`'. $field .'` LIKE :search');
        $res->execute(array(':search' => '%'. $search[0] .'%'));

        $rows[$key. '-data'] = $res->fetchAll(PDO::FETCH_ASSOC);
    }
} else {
    foreach ($fields as $key => $field)
    {
        $res = $handler->prepare($sql. '`'. $field .'` LIKE :search');
        $res->execute(array(':search' => '%'. $search[0] .'%'));

        $rows[$key. '-data'] = $res->fetchAll(PDO::FETCH_ASSOC);
    }
}

注意:$search$search = explode(' ', $_POST['serach']);生成

2)删除重复值

$rows = array_map('unserialize', array_unique(array_map('serialize', $rows)));

3)在这里,我尝试将爆炸的搜索词与数组中的值进行匹配:

foreach ($rows as $result)
{
    $result = array_filter(
        $result,
        function($value)
        {
            return (count(array_diff($value, explode(' ', $_POST['search']))) > 0);
        }
    );

    # then use the $result to build shizzle
}

让我们举个例子吧,我们继续使用Honda XL作为搜索词,但是类似Honda CR的东西一直在返回(并且XL不会出现在字符串中的任何地方)。

因此,它实质上是建立第一个搜索词的大型数组,然后使用其他词来过滤结果。我要去哪里错了?

编辑:JSON输出作为要求。 (根据搜索字词:Honda XL生成)

[0…99]
​    0: {…}
​​​        attributes: {…}
​​​​            "data-cc": "600"​​​​
            "data-epid": "219723301"​​
            "data-make": "Honda"
​​​            "data-model": "XL"
​​​​            "data-street": "Transalp"
​​​​            "data-sub": "V"
​​​​            "data-year": "1999"
​​​​        <prototype>: Object { … }
​​​        checked: false
​​​        name: "Honda XL 600 1999 V Transalp"
​​​        value: "219723301"
​​​        <prototype>: Object { … }
​​    1: Object { name: "Honda CR 80 1980 R --", value: "219723391", checked: false, … }
​​    2: Object { name: "Honda SH i 150 2009 D --", value: "219723931", checked: false, … }
​​    3: Object { name: "Honda FJS 400 2012 A Silver Wing", value: "219723971", checked: false, … }
    4: Object { name: "Honda XL 250 1987 R --", value: "219723981", checked: false, … }

(仅作为示例,因为实际数据计数为> 3k)

2 个答案:

答案 0 :(得分:1)

如果没有差异

array_diff返回0。我们可以遍历每个查询结果并输出与搜索相关的数据。

foreach($rows as $row) { 
    foreach(array_filter($row, function($data) { 
        return count(array_diff(explode(' ', $_POST['search']), $data)) == 0; 
    }) as $data) { 
        var_dump($data); 
    }
}

答案 1 :(得分:0)

为什么在查询中不使用mysql concat函数来组合makemodel field and then search the string by = operator to do the exact match rather than LIKE`运算符