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查詢