The resumable query feature allows you to perform queries that can be resumed to fetch additional results. This is particularly useful for large result sets or when implementing pagination.

Synchronous Usage

Creating a Resumable Query

To create a resumable query, use the resumable_query method of the Index class:

query = index.resumable_query(
    vector=[0.1, 0.2],  # or use 'data' parameter for text-based queries
    top_k=2,
    include_metadata=True,
    include_vectors=True,
    namespace="your_namespace"
)

Parameters:

  • vector: A list of floats representing the query vector.
  • data: A string for text-based queries (mutually exclusive with vector).
  • top_k: The number of results to fetch initially.
  • include_metadata: Whether to include metadata in the results.
  • include_vectors: Whether to include vector values in the results.
  • max-idle: The maximum idle time for the query in seconds.
  • namespace: The namespace to query (optional).

Starting the Query

To start the query and get initial results:

initial_results = query.start()

The initial_results will be a list of result objects, each having properties like id and metadata (if included).

Fetching More Results

To fetch additional results:

next_results = query.fetch_next(number_of_results)

This method returns a list of additional results. If no more results are available, it returns an empty list.

Stopping the Query

When you’re done with the query, stop it to release resources:

stop_result = query.stop()
assert stop_result == 'Success'

Asynchronous Usage

For asynchronous operations, use the AsyncIndex class:

Creating an Async Resumable Query

query = await async_index.resumable_query(
  vector=[0.1, 0.2],
  top_k=2,
  include_metadata=True,
  include_vectors=True,
  namespace='your_namespace'
)

Starting the Async Query

initial_results = await query.async_start()

Fetching More Results Asynchronously

next_results = await query.async_fetch_next(number_of_results)

Stopping the Async Query

stop_result = await query.async_stop()
assert stop_result == 'Success'

Error Handling

After stopping a query, attempting to fetch more results or stop it again will raise a ClientError:

with pytest.raises(ClientError):
  query.fetch_next(1)
  query.async_fetch_next(1)

for async with pytest.raises(ClientError):
  query.stop() # or await query.async_stop() for async

Example: Fetching All Results Here’s an example of how to fetch all results using a resumable query:

query = index.resumable_query(
  vector=[0.1, 0.2],
  top_k=2,
  include_metadata=True
)
results = query.start()
while True:
  next_batch = query.fetch_next(2)
  if not next_batch:
    break
  results.extend(next_batch)
query.stop()

This pattern allows you to efficiently retrieve large result sets without loading everything into memory at once.

Remember to always stop your query when you’re done to release server-side resources.

Example

from upstash_vector import Index

# Create an index instance
index = Index()

# Upsert vectors into the index
index.upsert(
    vectors=[
        ("id1", [0.1, 0.2], {"field": "value1"}),
        ("id2", [0.3, 0.4], {"field": "value2"}),
        ("id3", [0.5, 0.6], {"field": "value3"}),
    ],
    namespace="example-namespace"
)

# Start a resumable query
query = index.resumable_query(
    vector=[0.1, 0.2],
    top_k=2,
    include_metadata=True,
    include_vectors=True,
    namespace="example-namespace"
)

# Fetch initial results
results = query.start()

# Access result data
for result in results:
    print(f"ID: {result.id}, Metadata: {result.metadata}")

# Stop the query when done
query.stop()