1. 程式人生 > 實用技巧 >PHP 中使用 ElasticSearch 的最佳實踐 (二)

PHP 中使用 ElasticSearch 的最佳實踐 (二)

引言

在上一篇文章當中,我們介紹瞭如何在 ElasticSearch 中建立索引以及建立欄位對映關係。
接下來的這篇文章,我們將在 Laravel 中對商品資訊進行增刪改查及搜尋。
記得 ElasticSearch 的核心應用場景,就如這句話一樣 "你知道了,為了搜尋"。
使用 ElasticSearch 就是為了提升資料的檢索速度。

部分實踐程式碼

建立商品

/**
 * 建立商品資料
 * @param Request $request
 * @return \Illuminate\Http\JsonResponse
 */
public function createProduct(Request $request)
{
    $title = $request->request->get(ProductModel::TITLE);
    $longTitle = $request->request->get(ProductModel::LONG_TITLE);
    $description = $request->request->get(ProductModel::DESCRIPTION);
    $sku = $request->request->get(ProductModel::SKU);
    $price = $request->request->get(ProductModel::PRICE);
    $sales = $request->request->get(ProductModel::SALES);

    $nowTime = date("Y-m-d H:i:s");
    // 商品資料寫入 DB
    $productId = DB::table(ProductModel::TABLE_NAME)->insertGetId([
        ProductModel::TITLE         => $title,
        ProductModel::LONG_TITLE    => $longTitle,
        ProductModel::DESCRIPTION   => $description,
        ProductModel::SKU           => $sku,
        ProductModel::PRICE         => $price,
        ProductModel::SALES         => $sales,
        ProductModel::CREATED_AT    => $nowTime,
        ProductModel::UPDATED_AT    => $nowTime
    ]);


    $params = [
        'body' => [
            ProductModel::PRODUCT_ID    => $productId,
            ProductModel::TITLE         => $title,
            ProductModel::LONG_TITLE    => $longTitle,
            ProductModel::DESCRIPTION   => $description,
            ProductModel::SKU           => $sku,
            ProductModel::PRICE         => $price,
            ProductModel::SALES         => $sales,
            ProductModel::CREATED_AT    => $nowTime,
            ProductModel::UPDATED_AT    => $nowTime
        ],
        'id'    => $productId,
        'index' => self::INDEX,
        'type'  => self::TYPE,
    ];

    // 商品資料寫入 ES
    $this->client->create($params);

    return Response()->json(['code' => 0, 'msg' => 'success']);
}

刪除商品

/**
 * 刪除商品資料
 * @param Request $request
 * @return \Illuminate\Http\JsonResponse
 */
public function deleteProduct(Request $request)
{
    $productId = $request->request->get(ProductModel::PRODUCT_ID);

    // 刪除 DB 中的商品資料
    DB::table(ProductModel::TABLE_NAME)->where(ProductModel::PRODUCT_ID, $productId)->delete();


    // 刪除 ES 中的商品資料
    $params = [
        'id'    => $productId,
        'index' => self::INDEX,
        'type'  => self::TYPE,
    ];
    $this->client->delete($params);

    return Response()->json(['code' => 0, 'msg' => 'success']);
}

更新商品

/**
 * 更新商品資料
 * @param Request $request
 * @return \Illuminate\Http\JsonResponse
 */
public function updateProduct(Request $request)
{
    $productId = $request->request->get(ProductModel::PRODUCT_ID);
    $title = $request->request->get(ProductModel::TITLE);
    $longTitle = $request->request->get(ProductModel::LONG_TITLE);
    $description = $request->request->get(ProductModel::DESCRIPTION);
    $sku = $request->request->get(ProductModel::SKU);
    $price = $request->request->get(ProductModel::PRICE);
    $sales = $request->request->get(ProductModel::SALES);

    $nowTime = date("Y-m-d H:i:s");
    // 商品資料更新到 DB
    DB::table(ProductModel::TABLE_NAME)
        ->where(ProductModel::PRODUCT_ID, $productId)
        ->update([
            ProductModel::TITLE         => $title,
            ProductModel::LONG_TITLE    => $longTitle,
            ProductModel::DESCRIPTION   => $description,
            ProductModel::SKU           => $sku,
            ProductModel::PRICE         => $price,
            ProductModel::SALES         => $sales,
            ProductModel::UPDATED_AT    => $nowTime
        ]);


    $params = [
        'body' => [
            ProductModel::PRODUCT_ID    => $productId,
            ProductModel::TITLE         => $title,
            ProductModel::LONG_TITLE    => $longTitle,
            ProductModel::DESCRIPTION   => $description,
            ProductModel::SKU           => $sku,
            ProductModel::PRICE         => $price,
            ProductModel::SALES         => $sales,
            ProductModel::CREATED_AT    => $nowTime,
            ProductModel::UPDATED_AT    => $nowTime
        ],
        'id'    => $productId,
        'index' => self::INDEX,
        'type'  => self::TYPE,
    ];

    // 商品資料更新到 ES
    $this->client->update($params);

    return Response()->json(['code' => 0, 'msg' => 'success']);
}

查詢單個商品

/**
 * 獲取單個商品資料
 * @param Request $request
 * @return \Illuminate\Http\JsonResponse
 */
public function getProductInfo(Request $request)
{
    $productId = $request->request->get(ProductModel::PRODUCT_ID);

    $params = [
        'id'    => $productId,
        'index' => self::INDEX,
        'type'  => self::TYPE,
    ];
    $this->client->get($params);

    return Response()->json(['code' => 0, 'msg' => 'success']);
}

搜尋商品

/**
 * 搜尋商品資料
 * @param Request $request
 * @return \Illuminate\Http\JsonResponse
 */
public function getProductList(Request $request)
{
    $params = [
        'index' => self::INDEX,
        'type'  => self::TYPE,
    ];
    $this->client->search($params);

    return Response()->json(['code' => 0, 'msg' => 'success']);
}

小結

這篇文章我們主要是介紹了,商品資料是先寫入到資料中,在同步到 ElasticSearch。那為什麼不直接寫入 ElasticSearch 呢?你知道的,
ElasticSearch 中的資料只是為了參與搜尋,而不參與其他的業務邏輯。因此,資料庫中儲存商品資料是必要的。

附:Github 程式碼地址