2019年9月30日14:36:15
提供一维数组模糊查询,只支持utf-8 内部处理是Unicode 编码特殊编码格式的可能会出错
if (!function_exists('arrayFuzzyQuery')) { /* * 提供一维数组value 模糊查询,只支持utf-8 内部处理是Unicode 编码特殊编码格式的可能会出错 * 注意:此方法可能会出现处理时间过长的问题 */ function arrayFuzzyQuery($string, array $array = [], $key = null) { if (empty($string)) { throw new Exception('查询参数不能为空'); } if (empty($array)) { throw new Exception('被查询数组为空'); } $return = []; //期望相似度比例 100为 100% $expectedRatio = 50; //同时使用全对比和相似度对比 foreach ($array as $k => $v) { if (empty($key)) { similar_text($string, $v, $percent); if (mb_substr_count($string, $v) > 0 || $percent >= $expectedRatio) { array_push($return, $v); } } else { similar_text($string, $v[$key], $percent); if (mb_substr_count($string, $v[$key]) > 0 || $percent >= $expectedRatio) { array_push($return, $v); } } } return $return; } }
注意: similar_text对英文支持效果好一点,中文对比效果差一点,根据实际业务需要 50%这个比例需要调整,经过几轮测试,效果还可以,基本够用,不嫌麻烦就添加到mysql数据库使用like OR elasticsearch
测试数据
$string = '水果西瓜'; $arrays = array( '0' => array('id' => 1, 'pid' => 0, 'name' => '水果'), '1' => array('id' => 2, 'pid' => 0, 'name' => '蔬菜'), '2' => array('id' => 3, 'pid' => 1, 'name' => '食品'), '3' => array('id' => 4, 'pid' => 2, 'name' => '运动'), '4' => array('id' => 5, 'pid' => 1, 'name' => '电脑'), '5' => array('id' => 6, 'pid' => '香果', 'name' => '香蕉'), '6' => array('id' => 7, 'pid' => 4, 'name' => '牛奶'), '7' => array('id' => 8, 'pid' => 5, 'name' => '西瓜'), '8' => array('id' => 9, 'pid' => 7, 'name' => '苹果'), ); // $rr = CommonService::getWarehouse($string, $arrays); $rr = arrayFuzzyQuery($string, $arrays, 'name'); pp($rr);