All Products
Search
Document Center

OpenSearch:Document search demo

Last Updated:Apr 01, 2026

This page shows how to query data from an OpenSearch Retrieval Engine Edition instance using the Python SDK. It covers four query patterns:

  • Havenask query with a query string

  • Havenask query with a constructed query

  • SQL query with a query string

  • SQL query with a constructed query

Prerequisites

Before you begin, ensure that you have:

  • Python 3.6 or later

  • The alibabacloud_ha3engine and alibabacloud_tea_util packages installed:

    pip install alibabacloud_ha3engine alibabacloud_tea_util
  • An OpenSearch Retrieval Engine Edition instance with a valid endpoint, instance ID, username, and password

Initialize the client

Create a Config object with your instance credentials, then pass it to client.Client to initialize the OpenSearch Retrieval Engine Edition V3.0 client.

# -*- coding: utf-8 -*-

from alibabacloud_ha3engine import models, client
from alibabacloud_tea_util import models as util_models
from Tea.exceptions import TeaException, RetryError

Config = models.Config(
    endpoint="ha-cn-7mz2ougaw02.ha.aliyuncs.com",
    instance_id="ha-cn-7mz2ougaw02",
    protocol="http",
    access_user_name="user",
    access_pass_word="111111"
)

# RuntimeOptions controls request timeouts and connection behavior.
# Use this with search_with_options() if you need custom timeout values.
runtime = util_models.RuntimeOptions(
    connect_timeout=5000,   # Milliseconds
    read_timeout=10000,     # Milliseconds
    autoretry=False,
    ignore_ssl=False,
    max_idle_conns=50
)

ha3EngineClient = client.Client(Config)
optionsHeaders = {}
Note

Both GET and POST methods are supported. GET is the default. If the query string exceeds 30 KB, use POST.

Run a Havenask query

Havenask queries let you search using either a raw query string or a structured query object built with the SDK.

Use a query string

Pass a raw Havenask query string directly to SearchQuery. This is the fastest way to run a query.

query_str = "config=hit:4,format:json,fetch_summary_type:pk,qrs_chain:search&&query=id:<pk>&&cluster=general"
haSearchQuery = models.SearchQuery(query=query_str)

# method is optional. Only GET and POST are supported. Default: GET.
haSearchRequestModel = models.SearchRequestModel(
    headers=optionsHeaders,
    query=haSearchQuery,
    method='POST'
)

hastrSearchResponseModel = ha3EngineClient.search(haSearchRequestModel)
print(hastrSearchResponseModel)

Use a constructed query

Build a structured query using SDK model objects. This approach gives you precise control over each clause — aggregate, config, sort, distinct, kvpairs, and filter.

# Aggregate clause: group results by a field and apply an aggregation function
aggregateClauses = []
haQueryAggregateClause = models.HaQueryAggregateClause(
    group_key="cate_id",              # Field to aggregate on
    agg_fun="count()",                # Aggregation function
    range="0~10",                     # Aggregation range
    max_group="5",                    # Maximum number of groups returned
    agg_filter="cate_id=1",           # Filter applied before aggregation
    agg_sampler_thres_hold="5",       # Sampling threshold
    agg_sampler_step="5",             # Sampling step size
)
aggregateClauses.append(haQueryAggregateClause)

# Config clause: control paging and result format
CustomConfig = dict()
CustomConfig.__setitem__("no_summary", "yes")
CustomConfig.__setitem__("qrs_chain", "search")
haQueryconfig = models.HaQueryconfigClause(
    start="1",          # Starting position for results
    hit="10",           # Number of results to return
    format="JSON",      # Return format: XML, JSON, or Protobuf
    custom_config=CustomConfig
)

# Sort clause: sort results by a field in ascending (+) or descending (-) order
haQuerySortClauseList = []
haQuerySortClause = models.HaQuerySortClause(
    sort_key="id",
    sort_order="+"      # + for ascending, - for descending
)
haQuerySortClauseList.append(haQuerySortClause)

# kvpairs: Havenask key-value parameters (DICT type)
haKvpairs = dict()
haKvpairs.__setitem__("uniqfield", "cate_id")

# Distinct clause: deduplicate results by a field
DistinctClauses = []
dist = models.HaQueryDistinctClause(
    dist_key="cate_id",         # Field to deduplicate on
    dist_count="1",             # Documents extracted per deduplication step
    dist_times="1",             # Number of deduplication steps
    reserved="false",           # Whether to keep remaining documents after extraction
    dist_filter="cate_id<=3",   # Filter applied during deduplication
    update_total_hit="false",   # Whether to subtract discarded documents from totalHits when reserved=false
    grade="1.2",                # Threshold for distinct extraction
)
DistinctClauses.append(dist)

# Custom query: additional query parameters
CustomQuery = dict()
CustomQuery.__setitem__("searcher_cache", "use:no")

# Assemble all clauses into a HaQuery object
haQuery = models.HaQuery(
    query="id:8148508889615505646",     # Query clause: index name and search term
    cluster="general",                  # Target cluster
    config=haQueryconfig,
    # Filter condition: supports =, >, <, <=, >=, !=; combine with AND or OR
    filter="id>100 AND id<=1000",
    aggregate=aggregateClauses,
    kvpairs=haKvpairs,
    sort=haQuerySortClauseList,
    distinct=DistinctClauses,
    custom_query=CustomQuery
)

searchQuery = models.SearchQuery(query=ha3EngineClient.build_ha_search_query(haQuery))
searchRequestModel = models.SearchRequestModel(optionsHeaders, searchQuery)

# Use POST if the query string exceeds 30 KB
haStructResponseModel = ha3EngineClient.search(query=searchRequestModel, method='POST')
print(haStructResponseModel)

Run an SQL query

SQL queries let you use standard SQL syntax to query your index. As with Havenask queries, use either a raw SQL string or a constructed query object.

Use a query string

sql_str = "select * from <indexTableName>&&kvpair=trace:INFO;formatType:json"
sqlsearchQuery = models.SearchQuery(sql=sql_str)
sqlSearchRequestModel = models.SearchRequestModel(optionsHeaders, sqlsearchQuery)

# Use POST if the query string exceeds 30 KB
sqlstrSearchResponseModel = ha3EngineClient.search(query=sqlSearchRequestModel, method='POST')
print(sqlstrSearchResponseModel)

Use a constructed query

sqlQueryKvpairs = dict()
sqlQueryKvpairs.__setitem__("trace", "INFO")
sqlQueryKvpairs.__setitem__("formatType", "full_json")

sqlQuery = models.SQLQuery(
    query="select * from odps",
    kvpairs=sqlQueryKvpairs
)

searchQuery = models.SearchQuery(sql=ha3EngineClient.build_sqlsearch_query(sqlQuery))
searchRequestModel = models.SearchRequestModel(optionsHeaders, searchQuery)

# Use POST if the query string exceeds 30 KB
sqlStructResponseModel = ha3EngineClient.search(query=searchRequestModel, method='POST')
print(sqlStructResponseModel)

Handle exceptions

Wrap your search calls in a try-except block to catch SDK errors and connection failures.

try:
    # Your search calls go here
    pass
except TeaException as e:
    print(f"send request with TeaException : {e}")
except RetryError as e:
    print(f"send request with Connection Exception  : {e}")

What's next