Search

Search and Scoring API Usage

You can either use the search API directly for a one-step operation, or call the following APIs separately for more control:

  • scoring – compute encrypted similarity scores.

  • decrypt_score – decrypt scores on the client side.

  • get_topk_metadata_results – retrieve top-k metadata entries using the decrypted scores.

Since the index metric is inner product (IP), vectors must be normalized before insertion and querying.


The simplest way is to call the search API directly, which performs scoring, decryption, and metadata retrieval internally.

import pyenvector as ev
import numpy as np

# Prepare normalized data
vecs = np.random.rand(100, 512)
vecs = vecs / np.linalg.norm(vecs, axis=1, keepdims=True)

# Initialize and insert
ev.init(address="localhost:50049", key_path="keys", key_id="example")
index = ev.create_index("example_index", dim=512)
metadata = [f"metadata_{i}" for i in range(100)]
index.insert(vecs, metadata)

# Perform search
search_index = ev.Index("example_index")
query = vecs[0]
result = search_index.search(query, top_k=2, output_fields=["metadata"])[0]

print(result)
# [{'id': 1, 'score': 0.9999, 'metadata': 'metadata_0'},
#  {'id': 59, 'score': 0.7888, 'metadata': 'metadata_58'}]

2. Scoring Only

Instead of full search, you can compute similarity scores in ciphertext. The query can be encrypted manually or by enabling query_encryption=True in index configuration.

search_index = ev.Index("example_index")
query = vecs[0]

# Encrypt query for secure scoring
encrypted_query = search_index.cipher.encrypt(query, "query")

# Perform scoring
scores = search_index.scoring(encrypted_query)

3. Decrypting Scores

Scores returned from scoring are encrypted. Use decrypt_score on the client side to reveal the plaintext values safely.

dec_scores = search_index.decrypt_score(scores)
print(dec_scores[:5])
# [0.7518, 0.7420, ..., 0.9999]

4. Retrieving Top-k Metadata

Once you have plaintext scores, you can request the top-k metadata separately.

topk_result = search_index.get_topk_metadata_results(
    dec_scores, top_k=2, output_fields=["metadata"]
)

print(topk_result)
# [{'id': 1, 'score': 0.9999, 'metadata': 'metadata_0'},
#  {'id': 59, 'score': 0.7888, 'metadata': 'metadata_58'}]

✅ Summary

  • Use search() if you want an all-in-one API.

  • Use scoring() + decrypt_score() + get_topk_metadata_results() if you need fine-grained control over each step.

  • For multi-query search, simply provide multiple queries at once (e.g., a 2D numpy array).

    • The results will be returned as a list, where each element corresponds to the result set of one query.

Example:

# Multi-query example
queries = vecs[:3]   # Take 3 queries
results = search_index.search(queries, top_k=2, output_fields=["metadata"])

for i, r in enumerate(results):
    print(f"Query {i} results:", r)

# Output:
# Query 0 results: [{'id': 1, 'score': 0.9999, 'metadata': 'metadata_0'}, ...]
# Query 1 results: [{'id': 42, 'score': 0.8123, 'metadata': 'metadata_41'}, ...]
# Query 2 results: [{'id': 59, 'score': 0.7888, 'metadata': 'metadata_58'}, ...]

Last updated