The HYBRID_SEARCH clause uses a JSON string to specify full-text search, vector search, and filtering conditions in a single SELECT statement, and returns rows ranked by a fusion strategy.
Notice
This syntax is only applicable in MySQL-compatible mode.
Syntax
SELECT select_expr_list
FROM HYBRID_SEARCH(TABLE table_name, dsl_string) [table_alias];
-- The select_expr_list is the SELECT list, which follows the standard SELECT syntax.
Parameters
Parameter |
Description |
|---|---|
table_name |
The name of the target table. Only heap tables (ORGANIZATION = HEAP) are supported. The table can be partitioned or non-partitioned. |
dsl_string |
A JSON string that describes query, knn, rank, rerank, from, size, min_score, and other parameters.
NoticeExcept for the differences listed in the "Global limits and notes" section, the syntax structure and parameter descriptions are consistent with those of |
Global limits and notes
This section lists only syntax limitations. For feature limitations, see Index-based hybrid search (SQL interface) in the References section and read the two sections together.
The description is as follows:
- The top-level
query(full-text search) andknn(vector search) operations can have at most three subqueries: one forquery, and forknn, one for objects and one per element for arrays. The total number of subqueries cannot exceed three, and at least one full-text or vector search operation must be included. - Column names in queries are case-insensitive.
- For the
query_vectorparameter in vector queries, it is recommended to input vectors as strings. - The
min_scoreparameter is supported only by the SQL interface and not by the PL interface. - Each
queryand eachknnis an independent search path, and theirfiltersdo not affect each other. If a filtering condition is required for a particular query path, the correspondingfiltermust be specified separately within that path. All search results are merged into a single result set, scored and ranked using a fusion algorithm, and the topsizeresults are returned. - The
rerankparameter must be used with eitherqueryorknn. It cannot be used alone. Coarse ranking is performed before reranking, andrerankcannot replace the fusion capability ofrank.
The limitations are as follows:
- The
rank_feature,es_mode, and_sourceparameters are not supported. - You cannot directly use
WHERE,ORDER BY, orLIMITon the same level asHYBRID_SEARCH. If further filtering or sorting is required, process the hybrid search results as a subquery. For example:-- Not supported: Using WHERE in the same layer as HYBRID_SEARCH SELECT id FROM HYBRID_SEARCH(TABLE doc_table, '{"knn":{"field":"vector","k":5,"query_vector":"[1,2,3]"}}') WHERE id > 3; -- Supported: Subquery first, then filtering SELECT id FROM ( SELECT id FROM HYBRID_SEARCH(TABLE doc_table, '{"knn":{"field":"vector","k":5,"query_vector":"[1,2,3]"}}') ) t WHERE id > 3; - Some nested JSON/ARRAY element paths cannot be pushed down. For example, if the
pathof ajsonelement is anarrayand the element is ajson, you cannot specify a path for thisjsonelement. - Scalar query conditions include
term,range,terms,wildcard, JSON expressions, and ARRAY expressions. Of these,wildcardcontributes to scoring in the top-levelquery,bool.must, andbool.should. Inbool.filter,bool.must_not, orknn.filter, it is used only as a filter. Other scalar query conditions do not contribute to scoring, do not supportboost, and cannot be used in themustorshouldclause of aboolquery. - The
boostvalues of non-top-level full-text queries andboolqueries, as well as column and token weights in full-text queries, must be greater than0. In all other cases,boostmust be greater than or equal to0. - The multiple full-text columns for
multi_matchorquery_stringqueries must use the same character set andcollation, and the full-text indexes must use the sameparser. - When
match,multi_match, orquery_stringis used for term-level matching, the corresponding full-text column should useFTS_INDEX_TYPE = MATCH(or the default type equivalent toMATCHif not specified).match_phraseapplies only to full-text index columns for whichFTS_INDEX_TYPE = PHRASE_MATCHhas been created.
Syntax of DSL_STRING parameters
dsl_string is a JSON-formatted string. This section describes its syntax in detail. Read it together with the parameter descriptions and examples below.
Suggested reading order
First, review the DSL_STRING parameter skeleton example to understand its top-level fields. Then, refer to the BNF blocks under Syntax definition as needed. For field meanings and constraints, see the Detailed parameter description table. For end-to-end table creation and scenario examples, see Index-based hybrid search (SQL interface) in the References section.
Syntax
This section describes the meaning and usage rules of BNF (Backus-Naur Form) syntax symbols:
Optional elements
[ ]indicates that multiple elements are optional in BNF. For example,param_list = param [, param]*meansparam_listcan contain one or moreparamelements.- The
[ ]inrank_expressionalso indicates that the sub-parameter is optional. [, "boost" : boost_value]indicates that this sub-parameter is optional in expressions that supportboost.term/range/termsand JSON/ARRAY scalar expressions do not supportboost.
Array representation
[ ]indicates an array in a JSON structure, for example,[condition_list].
Alternatives
|separates alternatives. For example,param = "query" | "knn"means thatparamcan be eitherqueryorknn.
Repetition
*indicates zero or more repetitions. For example,param_list = param [, param]*indicates thatparam_listcan contain one or moreparamelements.
Requirements for JSON format
- All JSON column names and string values must be enclosed in double quotes.
- Numbers do not need to be enclosed in double quotes.
Syntax definition
This section describes the syntax of dsl_string. For parameter descriptions, see the table below.
DSL_STRING skeleton example
The following dsl_string skeleton is equivalent to the "Full-text and vector RRF hybrid search" example below. The top level can contain query for full-text search, knn for vector search, rank for fusion and coarse ranking, rerank for model-based reranking, and from and size for pagination. When only one search path is needed, remove the unnecessary top-level keys. The SQL interface also supports min_score; see the parameter table for details.
SELECT * FROM HYBRID_SEARCH(
TABLE doc_table,
'{
"query": {
"match": {
"content": "oceanbase mysql"
}
},
"knn": {
"field": "vector",
"k": 5,
"query_vector": "[1,2,3]"
},
"rank": {
"rrf": {
"rank_window_size": 10,
"rank_constant": 60
}
},
"rerank": {
"model": "rerank_model",
"field": "content",
"query": "oceanbase mysql",
"rank_window_size": 10
},
"from": 0,
"size": 10
}'
);
Top-level parameters structure
The top-level parameter structure is used to specify the parameters for hybrid search.
dsl_string = '{param_list}'
param_list = param [, param]*
-- At least one of query and knn must be selected; they can be used together for hybrid search.
param = "query" : {query_expression | search_options} --The query expression or options.
| "knn" : {knn_expression}
| "rank" : {rank_expression}
| "rerank" : {rerank_params} -- Supported starting from V4.6.0 BP1
| "from" : number
| "size" : number
| "min_score" : number -- Supported only for the SQL interface.
Query expression structure
Query expression syntax is used to specify full-text and scalar query conditions in a hybrid search, and supports configuring query options.
query_expression = bool_query | scalar_term | fulltext_term
bool_query = "bool" : {bool_condition_list}
bool_condition_list = bool_condition [, bool_condition]*
bool_condition = "must" : [condition_list]
| "should" : [condition_list]
| "must_not" : [condition_list]
| "filter" : [condition_list]
| "boost" : boost_value
condition_list = query_expression [, query_expression]*
In bool, the values for must / should / must_not / filter are all arrays of query expressions. Each element in the array is a complete query_expression (which can further nest bool or be followed by match / term, etc.). The following example shows only the inner fragment of a query object:
{
"bool": {
"must": [
{
"match": {
"content": "oceanbase"
}
}
],
"filter": [
{
"term": {
"status": 1
}
}
]
}
}
Scalar query structure
This structure defines scalar query expressions, including range_query, term_query, terms_query, and wildcard_query, which represent range queries, exact matches, multi-value matches, and wildcard matches, respectively.
scalar_term = range_query | term_query | terms_query | wildcard_query
range_query = "range" : {"field_name" : {range_condition_list}}
range_condition_list = range_condition [, range_condition]*
range_condition = "gte" : number
| "gt" : number
| "lte" : number
| "lt" : number
term_query = "term" : {term_condition_list}
term_condition_list = term_condition [, term_condition]*
term_condition = "field_name" : scalar_value
| "field_name" : term_value_object
term_value_object = "value" : scalar_value
terms_query = "terms" : {terms_condition_list}
terms_condition_list = terms_condition [, terms_condition]*
terms_condition = "field_name" : [scalar_value_list]
scalar_value_list = scalar_value [, scalar_value]*
wildcard_query = "wildcard" : {wildcard_condition_list} -- Supported starting from V4.6.0 BP1
wildcard_condition_list = wildcard_condition [, wildcard_condition]*
wildcard_condition = "field_name" : wildcard_pattern
| "field_name" : {wildcard_value_object}
wildcard_pattern = "string_value" | number | boolean
wildcard_value_object = wildcard_value_body [, "boost" : boost_value]
wildcard_value_body = "value" : wildcard_pattern
| "wildcard" : wildcard_pattern
Full-text query structure
This structure defines full-text query expressions, including match_query, match_phrase_query, query_string, and multi_match, which represent term-level matching, phrase-level matching, full-text search, and multi-column term-level matching, respectively.
fulltext_term = match_query | match_phrase_query | query_string | multi_match
match_query = "match" : {"field_name" : match_body}
match_body = "string_value" | {match_condition}
match_condition = "query" : "string_value" [, "operator" : ("OR" | "AND")] [, "minimum_should_match" : number] [, "boost" : boost_value]
match_phrase_query = "match_phrase" : {"field_name" : phrase_body}
phrase_body = "string_value" | {phrase_condition}
phrase_condition = "query" : "string_value" [, "slop" : number] [, "boost" : boost_value]
query_string = "query_string" : {query_string_condition}
query_string_condition = "fields" : [field_weight_list]
| "query" : "string_value" -- Can contain the term-level weight operator ^. For details, see "Weight operator description" below.
| "boost" : boost_value
| "type" : ("best_fields" | "most_fields")
| "default_operator" : ("AND" | "OR")
| "minimum_should_match" : number
multi_match = "multi_match" : {multi_match_condition}
multi_match_condition = "fields" : [field_weight_list]
| "query" : "string_value" -- Does not support keyword-level ^ in the query string.
| "boost" : boost_value
| "type" : ("best_fields" | "most_fields")
| "operator" : ("AND" | "OR")
| "minimum_should_match" : number
field_weight_list = field_weight [, field_weight]*
field_weight = "field_name[^number]"
Query options structure
Note
The query options structure is supported starting from V4.6.0 BP1.
This structure configures query options such as intra-partition parallelism.
search_options = "search_options" : {search_options_body}
search_options_body = "query_dop" : number
{
"query": {
"search_options": {"query_dop": 4},
"match": {"content": "oceanbase mysql"}
}
}
Vector and sorting structures
This structure specifies vector search parameters, including the vector field, similarity, filter conditions, and weights. It supports both single-vector and multi-vector search.
knn_expression = "knn" : {knn_condition_list} | [multi_knn_condition_list]
knn_condition_list = knn_condition [, knn_condition]*
knn_condition = "field" : "field_name"
| "k" : number
| "query_vector" : [vector_values]
| "num_candidates" : number -- Supported starting from V4.6.0 BP1
| "search_options" : {search_option_list}
| "filter" : [condition_list]
| "similarity" : number
| "boost" : boost_value
search_option_list = search_option [, search_option]*
search_option = "ef_search" : number
| "refine_k" : number
| "filter_mode" : ("pre" | "pre-knn" | "pre-brute" | "post" | "post-index-merge")
multi_knn_condition_list = {knn_condition} [, {knn_condition}]*
vector_values = float [, float]*
rank_expression = "rank" : {rank_strategy}
rank_strategy = "rrf" : {rrf_params}
| "weighted_sum" : {weighted_sum_params}
rrf_params = "rank_window_size" : number [, "rank_constant" : number]
weighted_sum_params = "rank_window_size" : number [, "normalizer" : ("minmax" | "none")]
-- Supported starting from V4.6.0 BP1
rerank_params = "model" : "string_value"
| "field" : "field_name"
| "query" : "string_value"
| "rank_window_size" : number
| "type" : "string_value"
For single-vector search, knn is a single object. For multi-vector search, knn is an array of objects, where each element is a set of knn_condition. The following example shows the knn section for multi-vector search:
{
"knn": [
{
"field": "vector_a",
"k": 3,
"query_vector": "[1,0,0]"
},
{
"field": "vector_b",
"k": 3,
"query_vector": "[0,1,0]"
}
]
}
Basic type definitions
The following table describes the basic data types used in the preceding syntax.
field_name = "string_value"
field_list = field_name [, field_name]*
number = integer | decimal
boost_value = integer | float
boolean = true | false
scalar_value = "string_value" | number | boolean
Detailed parameter description
Expression type |
Parameter name |
Parameter description |
|---|---|---|
| Top-level keyword parameters | query | Can be used alone for full-text search or together with the knn parameter for hybrid search. Query options can be set, which are supported starting from V4.6.0 BP1. |
| knn | Can be used alone for single-vector or multi-vector search, or together with the query parameter for hybrid search. |
|
| rank (optional) | The fusion and coarse-ranking strategy for results from multiple recall paths. It supports rrf and weighted_sum, including the normalizer parameter. If omitted, the default fusion strategy is rrf. |
|
rerank (optional)
NoticeThis parameter is supported starting from V4.6.0 BP1. |
After coarse ranking, an AI reranking model reranks the candidate documents. This parameter must be used with query or knn. For details, see the rerank parameters below. |
|
| from (optional) | Specifies which row to return from the search result set. If not specified, the first row is returned by default. This parameter must be used together with the size parameter. |
|
| size (optional) | Specifies the number of rows to return. If not specified, the default value is 10. The relationship between size, rerank.rank_window_size, and rank must satisfy size ≤ rerank.rank_window_size ≤ rank. If size is not specified, it is treated as size = rerank.rank_window_size. |
|
| bool | must | Required. A score must be calculated. When boolean logic is needed internally, a bool expression must be nested. Multiple conditions in a bool expression are combined by default using the AND logic. |
| should | Should be satisfied, similar to OR, requires scoring. When boolean logic is needed internally, a bool expression must be nested. Multiple conditions within a bool expression are combined by default using the AND logic. | |
| must_not | Must Not: conditions that must not be met. If a condition is a must_not, it will not be scored and will be converted into a 'NOT' expression. Multiple must_not conditions are connected by 'AND'. When boolean logic is required internally, a bool expression must be nested. Multiple conditions within a bool expression are combined by default using the AND logic. A bool expression must contain at least one positive condition (must/should/filter). A bool expression with only one must_not condition is not supported. |
|
| filter | Must be met. No score is calculated. Converted to an 'AND' expression. When boolean logic is required internally, a bool expression must be nested. Multiple conditions in a bool expression are combined by default using the AND logic. | |
| boost (optional) | The query weight. For more information, see the description of the boost parameter below. Note: Scalar queries such as term, range, and terms do not support boost. |
|
| Scalar query (scalar_term) | range | Range search, used with gte, gt, lte, and lt. The field_name parameter is required. This type of scalar query does not contribute to scoring, does not support boost, and cannot be used in the must/should clause of a bool statement. |
| term | Exact match. Supports scalar values such as strings, numbers, and booleans, which are converted into SQL's '=' expression. Such scalar queries do not contribute to scoring, do not support boost, and cannot be used in the must/should clause of a bool statement. |
|
| terms | Exactly matches any value in the specified set. Supports arrays of scalar values such as strings, numbers, and booleans, which are converted into SQL's 'IN' expression. This type of scalar query does not contribute to scoring, does not support boost, and cannot be used in the must/should clause of a bool statement. |
|
| wildcard | Wildcard fuzzy search is supported, which is equivalent to using the LIKE ... ESCAPE '\\' clause in SQL.* represents any multiple characters (equivalent to % in SQL), and ? represents any single character (equivalent to _ in SQL).There are three usage methods: directly write a wildcard string (for example, {"wildcard": {"title": "ab*cd?"}}), use the value field (for example, {"wildcard": {"title": {"value": "ab*cd?", "boost": 0.5}}}), or use the wildcard field (for example, {"wildcard": {"title": {"wildcard": "ab*cd?", "boost": 0.5}}}). You can only choose either value or wildcard, not both. An incorrect example is {"wildcard": {"title": {"value": "abc", "wildcard": "cbd"}}}. The case_insensitive, rewrite, and _name parameters are not supported.The boost parameter is supported.
NoteThis feature is available starting with V4.6.0 BP1. |
|
| Full-text query (fulltext_term) | match | Full-text match, performing term matching on a single column. The corresponding column must have a single-column full-text index created (FTS_INDEX_TYPE = MATCH or a type equivalent to the default). It supports the complete object form {"field":{"query":"...","operator":"OR|AND","minimum_should_match":n,"boost":...}}, or the simplified form when the optional sub-segments are omitted {"field":"query string"}. The query string is tokenized by the tokenizer used for the index; repeated occurrences of the same keyword only increase its weight and do not change whether a match is found. The operator specifies the logic between keywords, which is optional. The default is OR. OR means any keyword should be matched; AND means all keywords must be matched. minimum_should_match takes effect only when operator = OR. It is an integer in the range [0, INT32_MAX], which is optional. The default is 1; a value of 0 is treated as 1; when it is greater than or equal to the number of keywords, it is equivalent to operator = AND. |
| match_phrase | Full-text match, performing phrase matching on a single column. The corresponding column must have a single-column full-text index created with FTS_INDEX_TYPE = PHRASE_MATCH. The query can be in the complete object format {"field":{"query":"...","slop":n,"boost":...}} or the simplified format {"field":"phrase_string"}. Phrases are tokenized by the index's tokenizer; if a phrase contains a stopword, any token can match at that position. slop specifies the maximum allowable offset between tokens, with values from the set [0, INT32_MAX]. A value of 0 indicates an exact match, while positive integers indicate a fuzzy match (optional, default is 0). |
|
| query_string | Full-text match. Use the operator ^ on multiple columns to extend the query semantics. First, split the query into multiple groups using the operator; then match each group against the respective columns and summarize by column; finally, aggregate the scores of each group.Among the full-text search parameters, only query_string supports token-level weighting: you can use ^ followed by a positive floating-point number in the query to assign a weight to that keyword group.Must not contain reserved words (case-insensitive): OR, AND, NOT, TO; must not contain characters + - & | ! = < > ( ) [ ] { } " ~ * ? : \ / (shown as literal constraints in the documentation, but must be properly escaped in the actual JSON). |
|
| multi_match | Full-text match, performing term matching across multiple columns with a field-centric approach: each column scores the keywords separately and then the scores are aggregated. All columns must be single-column full-text indexes with consistent character sets and tokenizers.multi_match does not support token-level weights; it supports weights only at the column and query levels:
|
|
| Common parameters for full-text queries | fields | The list of columns for multi_match or query_string. You can add ^ to a column name followed by a positive floating-point number to specify the column weight, with a default value of 1.0. If the same column name appears multiple times, the weight of the last occurrence prevails. |
| query | The query string for multi_match or query_string. The query content for match or match_phrase is written in the query column (or directly as the column value string in its simplified form) under the respective column object. Keyword repetition only affects the weight. |
|
| minimum_should_match (Optional) | In match and multi_match, when operator = OR, this parameter specifies the minimum number of keywords that must match. The default is 1, and 0 is treated as 1. When minimum_should_match is greater than or equal to the number of keywords, the behavior is equivalent to AND.In query_string, when default_operator = OR, this parameter specifies the minimum number of groups that must match. A group consists of terms and a weight separated by ^. The same rules apply.
NoteWhen nested within a |
|
| boost (optional) | The query weight. For more information, see the boost parameter description below. | |
| type (optional) | The matching mode for multi_match or query_string. best_fields is supported, indicating to return the maximum value; most_fields is supported, indicating to sum the values. cross_fields and phrase are not supported. If not specified, the default is best_fields. |
|
| default_operator (Optional) | query_string only. The default logic between groups and between keywords within a group is as follows: OR indicates matching any group or keyword; AND indicates matching all. Optional. Default is OR. |
|
| operator (optional) | The keyword logic for match and multi_match: OR or AND. Optional. Default is OR. |
|
Query options (search_options)
NoteSupported starting from V4.6.0 BP1. |
||
| query_dop (optional) | Specifies the number of parallel threads for partition-wise execution of the hybrid search query recall path. Parallelism is supported only for full-text and scalar paths; vector paths are not supported. Each query recall path can have only one query_dop value. It is an integer in the range [1, 128], with a default value of 1. A value of 1 disables intra-path parallelism. Values greater than 1 split the data range for parallel scanning. Values outside the range cause an error during JSON parsing. This parameter takes effect only when hybrid search parallel execution is enabled and can be used with query hints. For details, see the parallel-execution section in Index-based hybrid search (SQL interface) in the References section. |
|
knn (vector search) |
||
| field | The name of the vector search column. | |
| k | The number of nearest neighbors returned in the end. Value range: [1, 16384]. |
|
| query_vector | Specifies the search vector. | |
| num_candidates (optional) | Specifies the vector-search candidate set size and is equivalent to ef_search. It is an integer in the range [1, 10000]; values outside the range cause an error. When filter_mode is post or post-index-merge, this parameter serves as an initial budget rather than an absolute upper limit. When it is set together with ef_search, the precedence rules and detailed examples are described in the "num_candidates and ef_search" section below.
NoteThis feature is supported starting from V4.6.0 BP1. |
|
| search_options (optional) | Advanced options for vector search, including ef_search, refine_k, and filter_mode. The value of ef_search is an integer in the range [1, 10000]. refine_k is a floating-point number in the range [1.0, 1000.0] that adjusts the reranking ratio for quantized vector indexes. It can take effect even when set together with num_candidates. filter_mode is a string that controls the execution path of vector queries with filter conditions. For valid values and their meanings, see the "filter_mode" section below. In an execution plan, this parameter may be displayed as a number, for example, filter_mode=0. |
|
| filter (optional) | The filter condition within the vector branch, which can include scalar expressions (including wildcard). |
|
| similarity (optional) | Specifies the filter conditions for vector similarity calculation. | |
| boost (optional) | The query weight. For more information, see the description of the boost parameter below. | |
rank (coarse ranking) |
rrf | The RRF (Reciprocal Rank Fusion) sorting strategy is used to fuse and rank multiple query results during hybrid search. |
| rank_window_size (optional) | This value specifies the size of the single result set returned by each query. A larger value indicates a higher degree of relevance but comes with performance overhead. The final sorted result set will be trimmed to the size specified in the search request.rank_window_size must satisfy both of the following conditions:
size parameter. |
|
| rank_constant (optional) | This value controls the influence of each document in the result set returned by each query on the final ranking. A larger value gives lower-ranked documents more influence on the final result. The default value is 60. |
|
rerank (reranking)
NoticeThis parameter is supported starting from V4.6.0 BP1. |
model | Required. The name of the reranking model. The value must be in the provider/model format, for example, aliyun-dashscope/gte-rerank-v2. You must register the provider by using the REGISTER_PROVIDER statement before you use this model. |
| field | Required. The name of the text column used for reranking. The column must exist in the query table and be of type CHAR, VARCHAR, or TEXT. |
|
| query | Required. The query string used to compare relevance with the document text. | |
| rank_window_size (Optional) | The number of candidate documents used for reranking. Value range: [0, 10000]. Default value: 10. It must satisfy rank_window_size ≥ size. If rank is also specified, it must not exceed rank.rank_window_size. |
|
| type (optional) | The reranking implementation type. The default is model, which calls an external reranking model. |
Weight operator description
The weight operator ^ specifies a weight at the column level or token level in a full-text query. The syntax is column_name^weight or keyword^weight, for example, "title^2.0". The following forms are supported:
- Column-level weights are supported only for
multi_matchandquery_string. - Only
query_stringsupports per-token weights.
The token-level weight operator specifies the weight of the keyword to its left (up to the space). Keywords without a weight operator have a default weight of 1.0. A keyword associated with a weight operator or a sequence of consecutive keywords without weight operators forms a group.
{
"query": {
"query_string": {
"fields": ["title^2.0", "content"],
"query": "apple banana orange^1.5 pear^1.2 blueberry mangosteen"
}
}
}
As shown in the preceding example, the query string "apple banana orange^1.5 pear^1.2 blueberry mangosteen" is divided into four groups: apple and banana with the default weight of 1.0, orange with a weight of 1.5, pear with a weight of 1.2, and blueberry and mangosteen with the default weight of 1.0.
Weight operators can be used together with the boost parameter. For specific examples, see the boost parameters section below.
Detailed description of boost parameters
The boost parameter specifies the weight of a query condition in the final relevance calculation. The value must be greater than or equal to 0. If omitted, the default is 1. In the syntax structure above, bool, scalar_term, single-vector search, and multi-vector search (knn) support the boost parameter, subject to the following rules:
Expressions that support
boostboolqueries.- Full-text queries (such as
match,match_phrase,query_string, andmulti_match). - Vector queries (single-vector or multi-vector
knn). - Scalar query:
wildcardquery.
Expressions that do not support
boost- Scalar query:
term/range/terms. - JSON or ARRAY scalar expressions.
- Scalar query:
Value constraints
- The
boostvalues of non-top-level full-text queries andboolqueries, as well as column and token weights in full-text queries, must be greater than0. - In all other cases,
boostmust be greater than or equal to0.
- The
Examples
a. Query level
boost(bool):{ "bool": { "filter": [{"term": {"category": "Gaming"}}], "boost": 2.0 } }b. Column-level weights (
query_string):{ "query_string": { "fields": ["product_name^2.0", "description^1.0"], "query": "gaming keyboard", "boost": 1.5 } }c. Vector query
boost(knn):{ "knn": { "field": "vector", "k": 5, "query_vector": "[1,2,3]", "boost": 1.5 } }
num_candidates and ef_search
This section describes the priorities of num_candidates and ef_search.
Note
num_candidates is supported starting with V4.6.0 BP1.
The priorities of num_candidates and ef_search are as follows:
Settings |
Effective Behavior |
|---|---|
Only num_candidates is set |
num_candidates takes effect, and ef_search = num_candidates. |
Only search_options.ef_search is set |
The specified ef_search takes effect. |
Both num_candidates and search_options.ef_search are set |
num_candidates takes precedence, and the final ef_search equals num_candidates. |
| Neither is set | The default system- or session-level ef_search value is used. |
filter_mode
filter_mode is a parameter in search_options that controls the execution path for vector queries with filter conditions. Valid values are as follows:
Value |
Meaning |
|---|---|
pre |
Adaptive Pre-filtering |
pre-knn |
Pre-filtering + KNN |
pre-brute |
Pre-filtering + brute-force search |
post |
Iterative filtering based on expressions |
post-index-merge |
Iterative filtering based on the index-merge framework |
wildcard scalar queries
This section describes additional information about wildcard scalar queries, including usage scenarios and index support.
Note
This feature is supported starting from V4.6.0 BP1.
Supported usage:
- In the top-level
query - In
bool.must - In
bool.should - In
bool.filter - In
bool.must_not - In
knn.filter(semantics consistent withbool.filter)
The index capabilities are as follows:
Index type |
Supported |
|---|---|
Regular index on a VARCHAR column |
Supported. Non-exact LIKE queries can use an index scan. |
| Prefix index | Not supported |
| Full-text index | Not supported |
| JSON SEARCH INDEX | Not supported |
| JSON CAST index | Not supported |
Examples
The following examples illustrate complex syntax for your reference.
Full-text and vector RRF hybrid search
Create a sample table containing a vector column, create a vector index on it, and create full-text indexes on the two VARCHAR columns.
CREATE TABLE doc_table(c1 INT, vector VECTOR(3), query VARCHAR(255), content VARCHAR(255), VECTOR INDEX idx1(vector) WITH (distance=l2, type=hnsw, lib=vsag), FULLTEXT INDEX idx2(query), FULLTEXT INDEX idx3(content));
Insert data.
INSERT INTO doc_table VALUES(1, '[1,2,3]', "hello world", "oceanbase Elasticsearch database"),
(2, '[1,2,1]', "hello world, what is your name", "oceanbase mysql database"),
(3, '[1,1,1]', "hello world, how are you", "oceanbase oracle database"),
(4, '[1,3,1]', "real world, where are you from", "postgres oracle database"),
(5, '[1,3,2]', "real world, how old are you", "redis oracle database"),
(6, '[2,1,1]', "hello world, where are you from", "starrocks oceanbase database");
SELECT * FROM HYBRID_SEARCH(
TABLE doc_table,
'{
"query": {
"match": {"content": "oceanbase mysql"}
},
"knn": {
"field": "vector",
"k": 5,
"query_vector": "[1,2,3]"
},
"rank": {
"rrf": {
"rank_constant": 60,
"rank_window_size": 10
}
}
}'
);
The expected return result is as follows:
+------+---------+---------------------------------+----------------------------------+----------------------+
| c1 | vector | query | content | __score |
+------+---------+---------------------------------+----------------------------------+----------------------+
| 1 | [1,2,3] | hello world | oceanbase Elasticsearch database | 0.03252247488101534 |
| 2 | [1,2,1] | hello world, what is your name | oceanbase mysql database | 0.032266458495966696 |
| 3 | [1,1,1] | hello world, how are you | oceanbase oracle database | 0.031754032258064516 |
| 5 | [1,3,2] | real world, how old are you | redis oracle database | 0.016129032258064516 |
| 6 | [2,1,1] | hello world, where are you from | starrocks oceanbase database | 0.016129032258064516 |
| 4 | [1,3,1] | real world, where are you from | postgres oracle database | 0.015625 |
+------+---------+---------------------------------+----------------------------------+----------------------+
6 rows in set
Set both num_candidates and ef_search
This example shows setting both num_candidates and ef_search:
-- When both num_candidates and search_options.ef_search are specified: num_candidates takes precedence.
SELECT c1 FROM HYBRID_SEARCH(TABLE doc_table, '{
"knn": {
"field": "vector",
"k": 10,
"num_candidates": 2000,
"query_vector": "[0.712338,0.603321,0.133444]",
"search_options": {
"ef_search": 101,
"refine_k": 5.6,
"filter_mode": "pre"
}
}
}');
Wildcard matching examples
This example demonstrates common scenarios for wildcard scalar queries, including prefix matching on regular columns, JSON path matching, serving as a filter condition in knn.filter, and combined filtering with bool.must / bool.should:
-- Normal column prefix matching
SELECT * FROM HYBRID_SEARCH(TABLE doc_table, '{
"query": {"wildcard": {"title": "prefix*"}}
}');
-- JSON Path
SELECT * FROM HYBRID_SEARCH(TABLE doc_table, '{
"query": {"wildcard": {"doc_json.name": "alpha*"}}
}');
-- As a knn.filter
SELECT * FROM HYBRID_SEARCH(TABLE doc_table, '{
"knn": {
"field": "vector_col",
"k": 1,
"query_vector": "[0.1,0.1,0.1,0.1]",
"filter": [{"wildcard": {"doc_json.name": "alpha*"}}]
}
}');
-- bool.must / should combination
SELECT * FROM HYBRID_SEARCH(TABLE doc_table, '{
"query": {
"bool": {
"must": [
{"term": {"store_id": "20000"}},
{"bool": {
"should": [
{"wildcard": {"phone": "*1399*"}},
{"wildcard": {"order_no": "*2024061*"}}
],
"minimum_should_match": 1
}}
]
}
}
}');
References
- For more information about the syntax, scenarios, and examples, see Index-based hybrid search (SQL interface).
