PHP:Laravel 构建一个elasticsearch查询
ES可以用作数据库,但是不建议当数据库,所以一般只用来存储关键数据。查出ID之后再去数据库查
public function index(Request $request) { // 测试,后面应该进行封装 $page = $request->input('page',1); $size = 16; //构建es查询 $params = [ "index" => "products", "body" => [ "from" => ($page - 1) * $size, "size" => $size, "query" => [ "bool" => [ "filter" => [ [ "term" => [ "status" => true ] ], [ "term" => [ "audit_status" => 1 ] ], ], ], ], ], ]; //搜索 if ($search = $request->input('search', '')) { // 将搜索词根据空格拆分成数组,并过滤掉空项 $keywords = array_filter(explode(' ', $search)); $params['body']['query']['bool']['must'] = []; // 遍历搜索词数组,分别添加到 must 查询中 foreach ($keywords as $keyword) { $params['body']['query']['bool']['must'][] = [ 'multi_match' => [ 'query' => $keyword, 'fields' => [ 'title', 'long_title', ], ], ]; } } // 排序 if ($order = $request->input('order', '')) { // 是否是以 _asc 或者 _desc 结尾 if (preg_match('/^(.+)_(asc|desc)$/', $order, $m)) { // 如果字符串的开头是这 3 个字符串之一,说明是一个合法的排序值 if (in_array($m[1], ['price', 'sold_count', 'rating'])) { // 根据传入的排序值来构造排序参数 $params['body']['sort'] = [[$m[1] => $m[2]]]; } } } $result = app('es')->search($params); // 通过 collect 函数将返回结果转为集合,并通过集合的 pluck 方法取到返回的商品 ID 数组 $productIds = collect($result['hits']['hits'])->pluck('_id')->all(); // 通过 whereIn 方法从数据库中读取商品数据 $products = Product::query() ->whereIn('id', $productIds) // orderByRaw 可以让我们用原生的 SQL 来给查询结果排序 ->orderByRaw(sprintf("FIND_IN_SET(id, '%s')", join(',', $productIds))) ->get(); // 返回一个 LengthAwarePaginator 对象 $pager = new LengthAwarePaginator($products, $result['hits']['total']['value'], $perPage, $page, [ 'path' => route('products.index', false), // 手动构建分页的 url ]); return view('products.index', [ 'products' => $pager, 'filters' => [ 'search' => $search, 'order' => $order, ] ]); }
封装上面的es查询