---
title: "Query a Collection"
description: "How to run semantic searches against a Lucent collection, apply metadata filters, set score thresholds, and interpret scored results."
published: 2026-05-14T12:11:32.720116+00:00
updated: 2026-05-14T12:11:32.720116+00:00
tags: ["guide", "lucent", "querying", "retrieval"]
url: https://xiobjects.com/docs/xio/lucent/guides/query-collection
source: XI Objects
---

<!-- xion:doctype xion+markdown -->
<!-- xion:metadata
{
  "version": "1.0",
  "content_type": "application/xion\u002Bmarkdown",
  "source_type": "xi-content/doc",
  "generator": "xio-content-publisher/1.0.0",
  "generated": "2026-05-14T12:10:20.4259056\u002B00:00",
  "encoding": "utf-8",
  "render_intent": "markdown",
  "title": "Query a Collection",
  "slug": "xio/lucent/guides/query-collection",
  "copyright": "\u00A9 2026 XI Objects Inc"
}
-->

# Query a Collection

Lucent queries run as hybrid search over the specified collection: vector cosine similarity and BM25 full-text search run in parallel, fuse via Reciprocal Rank Fusion, and optionally pass through a re-ranker. The result is a ranked list of `ScoredChunk` objects.

## Basic query

```csharp
var result = await engine.QueryAsync("my-collection", new QueryRequest
{
    Text = "what is the cancellation policy",
    TopK = 10
});

foreach (var hit in result.Chunks)
{
    Console.WriteLine($"[{hit.Score:F3}] {hit.Chunk.Content.Substring(0, 100)}…");
    Console.WriteLine($"  Source: {hit.Chunk.Metadata.FilePath}, page {hit.Chunk.Metadata.PageNumber}");
}
```

`TopK` defaults to `10` if omitted. The returned list is ordered by descending fused score.

## Score threshold

Set `ScoreThreshold` to drop results below a minimum confidence. The fused score range is 0–1; a threshold around `0.35`–`0.4` is a reasonable starting point for cutting low-signal matches.

```csharp
var result = await engine.QueryAsync("my-collection", new QueryRequest
{
    Text = "data retention requirements",
    TopK = 20,
    ScoreThreshold = 0.35f
});
```

The threshold applies to the final fused score, after re-ranking if a scorer is configured. Results below the threshold are excluded from `result.Chunks` entirely.

## Metadata filters

Filter expressions narrow candidates before search, so filtered chunks never enter the ranking paths.

```csharp
using static Lucent.Filter;

var result = await engine.QueryAsync("policies", new QueryRequest
{
    Text = "GDPR compliance",
    TopK = 10,
    Filter = And(
        Eq("category", "legal"),
        In("status", ["approved", "published"]),
        Not(Eq("archived", "true"))
    )
});
```

Filters compose over chunk metadata. Structural fields (`PageNumber`, `SlideIndex`, etc.) and custom fields from `AddDocumentRequest.Metadata` are both queryable. For a full list of filter expressions, see [Hybrid Search](/docs/xio/lucent/concepts/hybrid-search#filters).

## Reading ScoredChunk

Each item in `result.Chunks` is a `ScoredChunk`:

```csharp
foreach (var hit in result.Chunks)
{
    var chunk = hit.Chunk;

    // Final ranked score (0–1)
    Console.WriteLine($"Score: {hit.Score:F3}");

    // Individual search signal scores
    Console.WriteLine($"Vector: {hit.VectorScore?.ToString("F3") ?? "n/a"}");
    Console.WriteLine($"Text:   {hit.TextScore?.ToString("F3") ?? "n/a"}");

    // Which search paths surfaced this chunk: "vector", "text", or "hybrid"
    Console.WriteLine($"Source: {hit.Source}");

    // Content and provenance
    Console.WriteLine($"Content:   {chunk.Content}");
    Console.WriteLine($"Document:  {chunk.DocumentId}");
    Console.WriteLine($"Page:      {chunk.Metadata.PageNumber}");
    Console.WriteLine($"Heading:   {chunk.Metadata.Heading}");
    Console.WriteLine($"Section:   {chunk.Metadata.SectionPath}");
}
```

`VectorScore` and `TextScore` are null when a chunk was surfaced by only one of the two search paths. Use `hit.Source` to distinguish: `"hybrid"` means it appeared in both, `"vector"` or `"text"` means it came from one path only.

## Timing breakdowns

`QueryResult` carries wall-clock durations for each pipeline stage:

```csharp
Console.WriteLine($"Embedding: {result.EmbeddingDuration.TotalMilliseconds:F0}ms");
Console.WriteLine($"Retrieval: {result.RetrievalDuration.TotalMilliseconds:F0}ms");
Console.WriteLine($"Scoring:   {result.ScoringDuration.TotalMilliseconds:F0}ms");
```

Embedding is typically the dominant cost on first query. Subsequent queries benefit from native ONNX Runtime warm-up.

## Querying XION attribution

In collections with XION-verified documents, filter by signer identity to restrict results to content from a specific source:

```csharp
using static Lucent.Filter;

var result = await engine.QueryAsync("verified-docs", new QueryRequest
{
    Text = "security requirements",
    Filter = Eq("attr_kid", "uH1O2KWkOIBYXvCfRbWphkGQdfAH6Ggx2GkjYih--O0")
});

foreach (var hit in result.Chunks)
{
    var attr = hit.Chunk.Metadata.Attribution;
    if (attr != null)
        Console.WriteLine($"Signed by {attr.KeyId} at {attr.SignedAt}");
}
```

Non-XION chunks have `Attribution == null`. Mixed collections work as expected: the filter applies only to XION chunks, non-XION chunks are excluded by the filter predicate.

## Python client

The Python client (`xio-lucent` on PyPI) exposes the same query interface:

```python
from xio_lucent import LucentClient

client = LucentClient("https://lucent.example.com", api_key="sk_live_…")

hits = await client.query(
    "my-collection",
    "cancellation policy",
    top_k=10,
    score_threshold=0.35
)

for hit in hits.chunks:
    print(f"[{hit.score:.3f}] {hit.chunk.content[:100]}")
```

## Next Steps

- [Hybrid Search](/docs/xio/lucent/concepts/hybrid-search) — understand RRF fusion, weights, and re-ranking
- [XRAG: Verified-Provenance RAG](/docs/xio/lucent/concepts/xrag) — query by signer identity and retrieve signed source bytes
- [REST API](/docs/xio/lucent/api/rest) — HTTP query endpoint and response shape
<!-- xion:trust
{
  "v": 1,
  "canon_v": 1,
  "ctx": "xiobjects.com/content",
  "hash_blake3_hex": "05a252917c173a97429131da2659a509fa8a956d4bd0cc115212cbffdfb70bd1",
  "hash_sha256_hex": null,
  "sig_alg": "ed25519",
  "sig_b64": "_B1CYp2Q_nBP_WUqGRUVNYopiDgpRJMkPAGf3_Mrc6JhwetM7OU_B1mier_ZBo8JN6UC_zMNW9TCcL8YsYI4DA",
  "pubkey_b64": "h-awvV8Rn-juph_c2Y7UH5A6e7NaFia3zBiMrJUOMOo",
  "x509_chain_pem": [
    "-----BEGIN CERTIFICATE-----\r\nMIIB9DCCAaagAwIBAgIQBrrNsmRlBvKQdA4idEliJjAFBgMrZXAwLjEsMCoGA1UE\r\nAwwjWEkgT2JqZWN0cyBJbmMgQ29udHJvbCBJbnRlcm1lZGlhdGUwHhcNMjYwNTEz\r\nMjI0NjA1WhcNMjYwNjEyMjI0NjA1WjBLMR4wHAYDVQQDDBV4aW8tY29udGVudC1w\r\ndWJsaXNoZXIxFzAVBgNVBAoMDlhJIE9iamVjdHMgSW5jMRAwDgYDVQQLDAdDb250\r\nZW50MCowBQYDK2VwAyEAh\u002BawvV8Rn\u002Bjuph/c2Y7UH5A6e7NaFia3zBiMrJUOMOqj\r\ngbwwgbkwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI\r\nKwYBBQUHAyQwZQYDVR0jBF4wXIAUOym3mFmw/qs1fgKrujCkxhrTk7KhLqQsMCox\r\nKDAmBgNVBAMMH0luc3RpdHV0ZSBvZiBQcm92ZW5hbmNlIFJvb3QgQ0GCFFJgN/ix\r\nQn72H6h3T5lEr9f8lJQFMB0GA1UdDgQWBBS1LSJi5\u002BeqBq8h974Ht9HTgIcdgTAF\r\nBgMrZXADQQCKjXbPwnk/DZHmLQstUWRzU6GSf\u002BSHTXTTZCtRLbmJKxT17Qlbpexc\r\nsRgdSpxNWpJPe9Fr4vwhRkESMqMIpgQO\r\n-----END CERTIFICATE-----\r\n",
    "-----BEGIN CERTIFICATE-----\r\nMIIByDCCAXqgAwIBAgIUUmA3\u002BLFCfvYfqHdPmUSv1/yUlAUwBQYDK2VwMCoxKDAm\r\nBgNVBAMMH0luc3RpdHV0ZSBvZiBQcm92ZW5hbmNlIFJvb3QgQ0EwHhcNMjUxMTAy\r\nMDMxNzEyWhcNMzAxMTAxMDMxNzEyWjAuMSwwKgYDVQQDDCNYSSBPYmplY3RzIElu\r\nYyBDb250cm9sIEludGVybWVkaWF0ZTAqMAUGAytlcAMhAFSS/pggSRmTcAMko7uc\r\nATH8OHgxVymd5mBFlPXbJkgio4GtMIGqMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYD\r\nVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQ7KbeYWbD\u002BqzV\u002BAqu6MKTGGtOTsjBlBgNV\r\nHSMEXjBcgBQAZRTDswSVORu\u002BkUOKX6WvrOvmQKEupCwwKjEoMCYGA1UEAwwfSW5z\r\ndGl0dXRlIG9mIFByb3ZlbmFuY2UgUm9vdCBDQYIUJqoJlpiSFg\u002B7W5IJLMrLttgR\r\nQp4wBQYDK2VwA0EA5FOht7YOsVRPp/FOKMQ\u002B3Mo9JxrvGR3ylKWAWNm6OUV7N3DB\r\nI9cD62wU5I0d0EKDBy0CX9DnoqUyxv5yguraAA==\r\n-----END CERTIFICATE-----\r\n",
    "-----BEGIN CERTIFICATE-----\r\nMIIBaTCCARugAwIBAgIUJqoJlpiSFg\u002B7W5IJLMrLttgRQp4wBQYDK2VwMCoxKDAm\r\nBgNVBAMMH0luc3RpdHV0ZSBvZiBQcm92ZW5hbmNlIFJvb3QgQ0EwHhcNMjUxMTAy\r\nMDMwNTEyWhcNMzUxMDMxMDMwNTEyWjAqMSgwJgYDVQQDDB9JbnN0aXR1dGUgb2Yg\r\nUHJvdmVuYW5jZSBSb290IENBMCowBQYDK2VwAyEAEWNZl\u002Br3IC7\u002BgBh90Yo1kWk1\r\npZCVzVuFdFT7qBBU8W2jUzBRMB0GA1UdDgQWBBQAZRTDswSVORu\u002BkUOKX6WvrOvm\r\nQDAfBgNVHSMEGDAWgBQAZRTDswSVORu\u002BkUOKX6WvrOvmQDAPBgNVHRMBAf8EBTAD\r\nAQH/MAUGAytlcANBAO6QeydOFNrN75qNyftggYudsxMyl4w9qWkSdZ6hlhrRcbSr\r\niG9Si0kbrIJOwYB/LTBU0RM4Rl\u002Bo9PM3Qp0mPwo=\r\n-----END CERTIFICATE-----\r\n"
  ],
  "key_id": "SDyVO7FvlAM-6CvQ62VZYOBO7JADFqLquUunUABRgKg",
  "created_at": "2026-05-14T12:10:20Z"
}
-->