Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sdk/cosmos/azure-cosmos/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Added support for Query Advisor feature - See [PR 45331](https://github.com/Azure/azure-sdk-for-python/pull/45331)
* Added `get_response_headers()` and `get_last_response_headers()` methods to the `CosmosItemPaged` and `CosmosAsyncItemPaged` objects returned by `query_items()`, allowing access to response headers from query operations. See [PR 44593](https://github.com/Azure/azure-sdk-for-python/pull/44593)
* Added InferenceRequestTimeout property for HttpTimeout Policy to Reranking API. See [45469](https://github.com/Azure/azure-sdk-for-python/pull/45469)
* Added `full_text_score_scope` parameter to `query_items()` for controlling BM25 statistics scope in hybrid search queries. Supports "Local" and "Global" (default) scopes. See [45686](https://github.com/Azure/azure-sdk-for-python/pull/45686)

#### Breaking Changes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
from azure.cosmos._execution_context.aio.base_execution_context import _QueryExecutionContextBase
from azure.cosmos._execution_context.aio import document_producer
from azure.cosmos._execution_context.hybrid_search_aggregator import _retrieve_component_scores, _rewrite_query_infos, \
_compute_rrf_scores, _compute_ranks, _coalesce_duplicate_rids, _attach_parameters
_compute_rrf_scores, _compute_ranks, _coalesce_duplicate_rids, _attach_parameters, \
_FULL_TEXT_SCORE_SCOPE_KEY, _FULL_TEXT_SCORE_SCOPE_LOCAL, _FULL_TEXT_SCORE_SCOPE_DEFAULT
from azure.cosmos._routing import routing_range
from azure.cosmos import exceptions

# pylint: disable=protected-access
RRF_CONSTANT = 60


class _Placeholders:
Expand Down Expand Up @@ -71,7 +71,11 @@ def __init__(self, client, resource_link, options, partitioned_query_execution_i
async def _run_hybrid_search(self): # pylint: disable=too-many-branches, too-many-statements
# Check if we need to run global statistics queries, and if so do for every partition in the container
if self._hybrid_search_query_info['requiresGlobalStatistics']:
target_partition_key_ranges = await self._get_target_partition_key_range(target_all_ranges=True)
# When FullTextScoreScope is "Local", use only target ranges for statistics.
# When "Global" (default), use all ranges.
full_text_score_scope = self._options.get(_FULL_TEXT_SCORE_SCOPE_KEY, _FULL_TEXT_SCORE_SCOPE_DEFAULT)
use_all_ranges = full_text_score_scope != _FULL_TEXT_SCORE_SCOPE_LOCAL
target_partition_key_ranges = await self._get_target_partition_key_range(target_all_ranges=use_all_ranges)
global_statistics_doc_producers = []
global_statistics_query = self._attach_parameters(self._hybrid_search_query_info['globalStatisticsQuery'])

Expand Down Expand Up @@ -99,8 +103,10 @@ async def _run_hybrid_search(self): # pylint: disable=too-many-branches, too-ma
except exceptions.CosmosHttpResponseError as e:
if exceptions._partition_range_is_gone(e):
# repairing document producer context on partition split
global_statistics_doc_producers = await self._repair_document_producer(global_statistics_query,
target_all_ranges=True)
global_statistics_doc_producers = await self._repair_document_producer(
global_statistics_query,
target_all_ranges=use_all_ranges
)
else:
raise
except StopAsyncIteration:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@

# pylint: disable=protected-access
RRF_CONSTANT = 60
_FULL_TEXT_SCORE_SCOPE_KEY = "fullTextScoreScope"
_FULL_TEXT_SCORE_SCOPE_LOCAL = "Local"
_FULL_TEXT_SCORE_SCOPE_DEFAULT = "Global"


class _Placeholders:
Expand Down Expand Up @@ -206,7 +209,11 @@ def __init__(self, client, resource_link, options,
def _run_hybrid_search(self): # pylint: disable=too-many-branches, too-many-statements
# Check if we need to run global statistics queries, and if so do for every partition in the container
if self._hybrid_search_query_info['requiresGlobalStatistics']:
target_partition_key_ranges = self._get_target_partition_key_range(target_all_ranges=True)
# When FullTextScoreScope is "Local", use only target ranges for statistics.
# When "Global" (default), use all ranges.
full_text_score_scope = self._options.get(_FULL_TEXT_SCORE_SCOPE_KEY, _FULL_TEXT_SCORE_SCOPE_DEFAULT)
use_all_ranges = full_text_score_scope != _FULL_TEXT_SCORE_SCOPE_LOCAL
target_partition_key_ranges = self._get_target_partition_key_range(target_all_ranges=use_all_ranges)
global_statistics_doc_producers = []
global_statistics_query = self._attach_parameters(self._hybrid_search_query_info['globalStatisticsQuery'])
partitioned_query_execution_context_list = []
Expand All @@ -233,8 +240,10 @@ def _run_hybrid_search(self): # pylint: disable=too-many-branches, too-many-sta
except exceptions.CosmosHttpResponseError as e:
if exceptions._partition_range_is_gone(e):
# repairing document producer context on partition split
global_statistics_doc_producers = self._repair_document_producer(global_statistics_query,
target_all_ranges=True)
global_statistics_doc_producers = self._repair_document_producer(
global_statistics_query,
target_all_ranges=use_all_ranges
)
else:
raise
except StopIteration:
Expand Down
24 changes: 24 additions & 0 deletions sdk/cosmos/azure-cosmos/azure/cosmos/aio/_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,7 @@ def query_items(
*,
continuation_token_limit: Optional[int] = None,
enable_scan_in_query: Optional[bool] = None,
full_text_score_scope: Optional[Literal["Local", "Global"]] = None,
initial_headers: Optional[dict[str, str]] = None,
max_integrated_cache_staleness_in_ms: Optional[int] = None,
max_item_count: Optional[int] = None,
Expand Down Expand Up @@ -574,6 +575,10 @@ def query_items(
in this list are specified as the names of the Azure Cosmos locations like, 'West US', 'East US' and so on.
If all preferred locations were excluded, primary/hub location will be used.
This excluded_location will override existing excluded_locations in client level.
:keyword Literal["Local", "Global"] full_text_score_scope: Sets the scope for computing BM25 statistics used
by FullTextScore in hybrid search queries. When set to "Global" (default), BM25 statistics are computed
across all documents in the container. When set to "Local", statistics are computed only over the subset
of documents within the partition key values specified in the query.
:keyword dict[str, str] initial_headers: Initial headers to be sent as part of the request.
:keyword int max_integrated_cache_staleness_in_ms: The max cache staleness for the integrated cache in
milliseconds. For accounts configured to use the integrated cache, using Session or Eventual consistency,
Expand Down Expand Up @@ -635,6 +640,7 @@ def query_items(
continuation_token_limit: Optional[int] = None,
enable_scan_in_query: Optional[bool] = None,
feed_range: dict[str, Any],
full_text_score_scope: Optional[Literal["Local", "Global"]] = None,
initial_headers: Optional[dict[str, str]] = None,
max_integrated_cache_staleness_in_ms: Optional[int] = None,
max_item_count: Optional[int] = None,
Expand Down Expand Up @@ -667,6 +673,10 @@ def query_items(
If all preferred locations were excluded, primary/hub location will be used.
This excluded_location will override existing excluded_locations in client level.
:keyword dict[str, Any] feed_range: The feed range that is used to define the scope.
:keyword Literal["Local", "Global"] full_text_score_scope: Sets the scope for computing BM25 statistics used
by FullTextScore in hybrid search queries. When set to "Global" (default), BM25 statistics are computed
across all documents in the container. When set to "Local", statistics are computed only over the subset
of documents within the partition key values specified in the query.
:keyword dict[str, str] initial_headers: Initial headers to be sent as part of the request.
:keyword int max_integrated_cache_staleness_in_ms: The max cache staleness for the integrated cache in
milliseconds. For accounts configured to use the integrated cache, using Session or Eventual consistency,
Expand Down Expand Up @@ -723,6 +733,7 @@ def query_items(
*,
continuation_token_limit: Optional[int] = None,
enable_scan_in_query: Optional[bool] = None,
full_text_score_scope: Optional[Literal["Local", "Global"]] = None,
initial_headers: Optional[dict[str, str]] = None,
max_integrated_cache_staleness_in_ms: Optional[int] = None,
max_item_count: Optional[int] = None,
Expand Down Expand Up @@ -754,6 +765,10 @@ def query_items(
in this list are specified as the names of the Azure Cosmos locations like, 'West US', 'East US' and so on.
If all preferred locations were excluded, primary/hub location will be used.
This excluded_location will override existing excluded_locations in client level.
:keyword Literal["Local", "Global"] full_text_score_scope: Sets the scope for computing BM25 statistics used
by FullTextScore in hybrid search queries. When set to "Global" (default), BM25 statistics are computed
across all documents in the container. When set to "Local", statistics are computed only over the subset
of documents within the partition key values specified in the query.
:keyword Dict[str, str] initial_headers: Initial headers to be sent as part of the request.
:keyword int max_integrated_cache_staleness_in_ms: The max cache staleness for the integrated cache in
milliseconds. For accounts configured to use the integrated cache, using Session or Eventual consistency,
Expand Down Expand Up @@ -843,6 +858,10 @@ def query_items(
None, it will perform a cross partition query. To learn more about using partition keys, see `here
<https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/cosmos/azure-cosmos/docs/PartitionKeys.md>`_.
:paramtype partition_key: ~azure.cosmos.partition_key.PartitionKeyType
:keyword Literal["Local", "Global"] full_text_score_scope: Sets the scope for computing BM25 statistics used
by FullTextScore in hybrid search queries. When set to "Global" (default), BM25 statistics are computed
across all documents in the container. When set to "Local", statistics are computed only over the subset
of documents within the partition key values specified in the query.
:keyword bool populate_index_metrics: Used to obtain the index metrics to understand how the query engine used
existing indexes and how it could use potential new indexes. Please note that this option will incur
overhead, so it should be enabled only when debugging slow queries.
Expand Down Expand Up @@ -902,6 +921,11 @@ def query_items(
feed_options["maxIntegratedCacheStaleness"] = max_integrated_cache_staleness_in_ms
if utils.valid_key_value_exist(kwargs, "continuation_token_limit"):
feed_options["responseContinuationTokenLimitInKb"] = kwargs.pop("continuation_token_limit")
if utils.valid_key_value_exist(kwargs, "full_text_score_scope"):
scope = kwargs.pop("full_text_score_scope")
if scope not in ("Local", "Global"):
raise ValueError(f"full_text_score_scope must be 'Local' or 'Global', got '{scope}'")
feed_options["fullTextScoreScope"] = scope

# populate availability_strategy
if (Constants.Kwargs.AVAILABILITY_STRATEGY in feed_options
Expand Down
27 changes: 23 additions & 4 deletions sdk/cosmos/azure-cosmos/azure/cosmos/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,7 @@ def query_items(
populate_query_metrics: Optional[bool] = None,
*,
continuation_token_limit: Optional[int] = None,
full_text_score_scope: Optional[Literal["Local", "Global"]] = None,
initial_headers: Optional[dict[str, str]] = None,
max_integrated_cache_staleness_in_ms: Optional[int] = None,
populate_index_metrics: Optional[bool] = None,
Expand Down Expand Up @@ -783,15 +784,19 @@ def query_items(
:param bool enable_scan_in_query: Allow scan on the queries which couldn't be served as
indexing was opted out on the requested paths.
:param bool populate_query_metrics: Enable returning query metrics in response headers.
:keyword int continuation_token_limit: The size limit in kb of the response continuation token in the query
response. Valid values are positive integers.
A value of 0 is the same as not passing a value (default no limit).
:keyword Literal["Local", "Global"] full_text_score_scope: Sets the scope for computing BM25 statistics used
by FullTextScore in hybrid search queries. When set to "Global" (default), BM25 statistics are computed
across all documents in the container. When set to "Local", statistics are computed only over the subset
of documents within the partition key values specified in the query.
:keyword bool populate_index_metrics: Used to obtain the index metrics to understand how the query engine used
existing indexes and how it could use potential new indexes. Please note that this option will incur
overhead, so it should be enabled only when debugging slow queries.
:keyword bool populate_query_advice: Used to obtain the query advice to understand aspects of the query that can
be optimized. Please note that this option will incur additional latency overhead, so it should be enabled
when debugging queries.
:keyword int continuation_token_limit: The size limit in kb of the response continuation token in the query
response. Valid values are positive integers.
A value of 0 is the same as not passing a value (default no limit).
:keyword Sequence[str] excluded_locations: Excluded locations to be skipped from preferred locations. The locations
in this list are specified as the names of the Azure Cosmos locations like, 'West US', 'East US' and so on.
If all preferred locations were excluded, primary/hub location will be used.
Expand Down Expand Up @@ -843,6 +848,7 @@ def query_items(
enable_cross_partition_query: Optional[bool] = None,
enable_scan_in_query: Optional[bool] = None,
feed_range: dict[str, Any],
full_text_score_scope: Optional[Literal["Local", "Global"]] = None,
initial_headers: Optional[dict[str, str]] = None,
max_integrated_cache_staleness_in_ms: Optional[int] = None,
max_item_count: Optional[int] = None,
Expand Down Expand Up @@ -878,6 +884,10 @@ def query_items(
If all preferred locations were excluded, primary/hub location will be used.
This excluded_location will override existing excluded_locations in client level.
:keyword dict[str, Any] feed_range: The feed range that is used to define the scope.
:keyword Literal["Local", "Global"] full_text_score_scope: Sets the scope for computing BM25 statistics used
by FullTextScore in hybrid search queries. When set to "Global" (default), BM25 statistics are computed
across all documents in the container. When set to "Local", statistics are computed only over the subset
of documents within the partition key values specified in the query.
:keyword dict[str, str] initial_headers: Initial headers to be sent as part of the request.
:keyword int max_integrated_cache_staleness_in_ms: The max cache staleness for the integrated cache in
milliseconds. For accounts configured to use the integrated cache, using Session or Eventual consistency,
Expand Down Expand Up @@ -929,7 +939,7 @@ def query_items(
...

@distributed_trace
def query_items( # pylint:disable=docstring-missing-param
def query_items( # pylint:disable=docstring-missing-param,too-many-statements
self,
*args: Any,
**kwargs: Any
Expand Down Expand Up @@ -968,6 +978,10 @@ def query_items( # pylint:disable=docstring-missing-param
None, it will perform a cross partition query. To learn more about using partition keys, see `here
<https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/cosmos/azure-cosmos/docs/PartitionKeys.md>`_.
:paramtype partition_key: ~azure.cosmos.partition_key.PartitionKeyType
:keyword Literal["Local", "Global"] full_text_score_scope: Sets the scope for computing BM25 statistics used
by FullTextScore in hybrid search queries. When set to "Global" (default), BM25 statistics are computed
across all documents in the container. When set to "Local", statistics are computed only over the subset
of documents within the partition key values specified in the query.
:keyword bool populate_index_metrics: Used to obtain the index metrics to understand how the query engine used
existing indexes and how it could use potential new indexes. Please note that this option will incur
overhead, so it should be enabled only when debugging slow queries.
Expand Down Expand Up @@ -1035,6 +1049,11 @@ def query_items( # pylint:disable=docstring-missing-param
feed_options["maxIntegratedCacheStaleness"] = max_integrated_cache_staleness_in_ms
if utils.valid_key_value_exist(kwargs, "continuation_token_limit"):
feed_options["responseContinuationTokenLimitInKb"] = kwargs.pop("continuation_token_limit")
if utils.valid_key_value_exist(kwargs, "full_text_score_scope"):
scope = kwargs.pop("full_text_score_scope")
if scope not in ("Local", "Global"):
raise ValueError(f"full_text_score_scope must be 'Local' or 'Global', got '{scope}'")
feed_options["fullTextScoreScope"] = scope

# populate availability_strategy
if (Constants.Kwargs.AVAILABILITY_STRATEGY in feed_options
Expand Down
Loading
Loading