跳至內容
ShopentlyLearn

取得 · 搜尋查詢 — 搜尋分析與規則

讀取「搜尋分析與規則」的資料。結果取決於此操作的參數。

GET/api/v1/search/queries/{query_hash}

身份驗證
Bearer
最低方案
STANDARD
所需權限
search.analytics:read

程式碼範例

請求示例

cURL

: "${SHOPENTLY_SHOP_URL:?}"

curl --disable --globoff --fail-with-body --silent --show-error \
  --proto '=https' --connect-timeout 5 --max-time 30 \
  --request GET \
  --header "Authorization: Bearer ${SHOPENTLY_ACCESS_TOKEN:?}" \
  --url "${SHOPENTLY_SHOP_URL%/}"'/api/v1/search/queries/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?limit=20'

PHP

<?php
declare(strict_types=1);

$baseUrl = rtrim(getenv('SHOPENTLY_SHOP_URL') ?: '', '/');
$origin = parse_url($baseUrl);
if (!$origin || ($origin['scheme'] ?? '') !== 'https' || empty($origin['host']) ||
    isset($origin['user'], $origin['pass']) || isset($origin['user']) || isset($origin['path']) ||
    isset($origin['query']) || isset($origin['fragment'])) {
    throw new RuntimeException('SHOPENTLY_SHOP_URL must be an HTTPS origin');
}
$credential = getenv('SHOPENTLY_ACCESS_TOKEN') ?: '';
if ($credential === '' || strpbrk($credential, "\r\n") !== false) {
    throw new RuntimeException('Invalid credential');
}
$headers = [];
$headers[] = 'Authorization: Bearer ' . $credential;
$responseHeaders = [];
$handle = curl_init($baseUrl . '/api/v1/search/queries/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?limit=20');
curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => false,
    CURLOPT_PROTOCOLS => CURLPROTO_HTTPS,
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_SSL_VERIFYHOST => 2,
    CURLOPT_CONNECTTIMEOUT => 5,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HEADERFUNCTION => static function ($handle, string $line) use (&$responseHeaders): int {
        if (str_contains($line, ':')) {
            [$name, $value] = explode(':', $line, 2);
            $responseHeaders[strtolower(trim($name))] = trim($value);
        }
        return strlen($line);
    },
]);
$raw = curl_exec($handle);
$status = curl_getinfo($handle, CURLINFO_RESPONSE_CODE);
$error = curl_error($handle);
curl_close($handle);
if ($raw === false) {
    throw new RuntimeException('Transport error: ' . $error);
}
if ($status < 200 || $status >= 300) {
    throw new RuntimeException('HTTP ' . $status . '; request_id=' .
        ($responseHeaders['x-request-id'] ?? '') . '; retry_after=' . ($responseHeaders['retry-after'] ?? ''));
}
$result = $raw === '' ? null : json_decode($raw, true, 512, JSON_THROW_ON_ERROR | JSON_BIGINT_AS_STRING);
echo json_encode($result, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;

Python

from contextlib import ExitStack
import json
import os
from urllib.parse import urlsplit

import requests  # python -m pip install requests

base_url = os.environ["SHOPENTLY_SHOP_URL"].rstrip("/")
origin = urlsplit(base_url)
if origin.scheme != "https" or not origin.hostname or origin.username or origin.password or origin.path or origin.query or origin.fragment:
    raise ValueError("SHOPENTLY_SHOP_URL must be an HTTPS origin")
credential = os.environ['SHOPENTLY_ACCESS_TOKEN']
if not credential or "\r" in credential or "\n" in credential:
    raise ValueError("Invalid credential")
headers = {}
headers["Authorization"] = 'Bearer' + " " + credential
body = None
if body is not None:
    headers["Content-Type"] = "application/json"

with ExitStack() as stack:
    session = stack.enter_context(requests.Session())
    files = None
    if False:
        image = stack.enter_context(open(os.environ["SHOPENTLY_IMAGE_FILE"], "rb"))
        if os.fstat(image.fileno()).st_size > 5242880:
            raise ValueError("Image exceeds 5 MiB")
        files = {"file": ("article.png", image, "image/png")}
    response = session.request(
        'GET', base_url + '/api/v1/search/queries/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?limit=20', headers=headers,
        data=body.encode("utf-8") if body is not None else None, files=files,
        timeout=(5, 30), allow_redirects=False,
    )
    if not 200 <= response.status_code < 300:
        raise RuntimeError(f"HTTP {response.status_code}; request_id={response.headers.get('X-Request-ID', '')}; retry_after={response.headers.get('Retry-After', '')}")
    if False:
        if response.headers.get("Content-Type") != "image/webp" or len(response.content) > 5242880:
            raise ValueError("Unexpected image response")
        with open(os.environ["SHOPENTLY_OUTPUT_FILE"], "xb") as output:
            output.write(response.content)
    else:
        result = response.json() if response.content else None
        print(json.dumps(result, ensure_ascii=False, indent=2))

回應示例 200

JSON
{
  "data": [
    {
      "category_id": "example",
      "category_result_count": 1,
      "currency_code": "PLN",
      "is_zero_results": false,
      "locale_code": "en",
      "market_id": "example",
      "max_price": "0.00",
      "min_price": "0.00",
      "occurred_at": "2026-01-01T12:00:00Z",
      "page": 1,
      "product_result_count": 1,
      "query_display": "example",
      "request_id": "example",
      "results": [
        {
          "clicked": false,
          "entity_id": "example",
          "entity_type": "product",
          "image_url": "https://example.invalid/product.jpg",
          "number": "example",
          "placement_source": "organic",
          "position": 1,
          "sku": "example",
          "slug": "example",
          "title": "example"
        }
      ],
      "sort_key": "example",
      "source": "results"
    }
  ],
  "meta": {
    "pagination": {
      "has_more": false,
      "limit": 20,
      "next_cursor": null
    },
    "period": {
      "as_of": "2026-01-02T00:00:00Z",
      "days": 1,
      "started_at": "2026-01-01T00:00:00Z"
    },
    "request_id": "example"
  }
}

工作原理

  • GET /api/v1/search/overview 和 /api/v1/search/queries 提供彙總統計與分組查詢。
  • 使用查詢的 query_hash 取得其發生記錄。
  • 報告期支援 7、30 或 90 天,各端點列出可用篩選條件。
  • 搜尋規則將短語與所選產品和分類關聯,支援建立、讀取、更新和刪除。
  • 規則與分析具有獨立權限;讀取搜尋統計不會授予配置權限。

參數

路徑參數

query_hash字串必填

分組搜尋短語的穩定識別碼。

約束
pattern
"^[a-f0-9]{64}$"
示例: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

查詢參數

limit整數選填

此頁記錄數上限。

minimum: 1maximum: 100
預設值: 50示例: 20
cursor字串 null選填

上一頁回傳的不透明續頁值。

字串:minLength: 1maxLength: 1024
days整數選填

報告期天數。

約束
enum
[7, 30, 90]
預設值: 30
locale字串 null選填

本次請求選擇的語言。

字串:minLength: 2maxLength: 20
約束 · 字串 1
pattern
"^[a-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$"
source字串 null選填

記錄活動的來源。

約束 · 字串 1
enum
["results", "autocomplete"]
market_id字串 null選填

上下文端點回傳的市場識別碼。

約束 · 字串 1
pattern
"^[a-z0-9][a-z0-9_-]{0,62}$"

此操作不接受 JSON 請求本文。

回應

回應 200

data陣列 <OccurrenceData > 必填

成功回應的資料。

欄位 · data

OccurrenceData

category_id字串 null必填

分類識別碼。

category_result_count整數必填

分類結果數量。

currency_code字串必填

幣種代碼。

is_zero_results布林值必填

搜尋是否未回傳結果。

locale_code字串必填

語言代碼。

market_id字串必填

上下文端點回傳的市場識別碼。

max_price字串 null必填

報告範圍內的最高價格。

min_price字串 null必填

報告範圍內的最低價格。

occurred_at字串必填

事件發生的日期和時間。

format: "date-time"
page整數必填

CMS 頁面資訊。

product_result_count整數必填

產品搜尋結果數量。

query_display字串必填

向管理員顯示的搜尋短語。

request_id字串必填

申請識別碼;在回應元資料中表示 HTTP 請求識別碼。

results陣列 <ResultSnapshotData > null必填

記錄的搜尋結果。

sort_key字串必填

排序鍵。

source字串必填

記錄活動的來源。

約束
enum
["results", "autocomplete"]
metaAnalyticsPageMeta AnalyticsMeta 必填

回應元資料。

欄位 · meta

AnalyticsPageMeta

paginationPagination 必填

遊標分頁元資料。

periodAnalyticsPeriodData 必填

報告期及其邊界。

request_id字串必填

申請識別碼;在回應元資料中表示 HTTP 請求識別碼。

minLength: 1maxLength: 100

AnalyticsMeta

periodAnalyticsPeriodData 必填

報告期及其邊界。

request_id字串必填

申請識別碼;在回應元資料中表示 HTTP 請求識別碼。

minLength: 1maxLength: 100
回應示例

HTTP 狀態

200
請求成功 架構
400
無效請求
401
需要身分驗證
403
權限不足
404
找不到資源
409
版本衝突
422
驗證失敗
429
超出請求限制
其他 HTTP 狀態 (7)
405
不允許的方法
413
請求過大
415
不支援的格式
500
伺服器錯誤
502
API 閘道錯誤
503
服務無法使用
504
閘道逾時

錯誤目錄: ErrorResponse

請求標頭與回應標頭

401

WWW-Authenticate字串選填

伺服器要求的身份驗證方案。

405

Allow字串選填

此資源支援的 HTTP 方法。

429, 503

Retry-After整數選填

重試前最少等待的秒數。

minimum: 0