首页 > 技术文章 > PHP:Laravel 构建一个elasticsearch查询

wish-yang 2021-02-24 14:22 原文

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

 

推荐阅读