PhoenixmlDb.Core
IndexConfiguration
Provides a fluent API for defining the indexes that accelerate XQuery and metadata queries on a container's documents.
#IndexConfiguration
Namespace: PhoenixmlDb.Core
Provides a fluent API for defining the indexes that accelerate XQuery and metadata queries on a container's documents.
Indexes are the primary mechanism for query performance in PhoenixmlDb. Without indexes, XQuery expressions require full document scans, which is acceptable for small collections but becomes slow as the number or size of documents grows.
When to define indexes: Indexes should be defined at container creation time via ContainerOptions.Indexes. Documents inserted after index creation are automatically indexed. However, existing documents are not retroactively indexed when new index definitions are added later.
Choosing the right index type: Each index type serves a different query pattern:
-
IndexConfiguration.AddNameIndexβ speeds up element/attribute name lookups (e.g.,//product). -
IndexConfiguration.AddPathIndexβ speeds up path expression evaluation (e.g.,//customer/address/city). -
IndexConfiguration.AddValueIndexβ enables typed range queries (e.g.,//product[price > 50],//order[date > xs:date('2024-01-01')]). -
IndexConfiguration.AddFullTextIndexβ enablesft:contains()full-text search on text content. -
IndexConfiguration.AddMetadataIndexβ enables efficient queries by document metadata key-value pairs. -
IndexConfiguration.EnableStructuralIndexβ maintains parent-child structural relationships for fast axis navigation (enabled by default).
The API is fluent β each method returns the IndexConfiguration instance, allowing chained calls.
#Example
A realistic index configuration for a product catalog:
var container = await db.CreateContainerAsync("products", opts =>
{
opts.Indexes
// Fast lookup by element name across all namespaces
.AddNameIndex()
// Accelerate path-based queries
.AddPathIndex("//product/@id")
.AddPathIndex("//product/category")
// Typed range queries on price and date
.AddValueIndex("//product/price", XdmValueType.XdmDecimal)
.AddValueIndex("//product/releaseDate", XdmValueType.Date)
// Full-text search on descriptions
.AddFullTextIndex("//product/description", new FullTextIndexOptions
{
Language = "en",
Stemming = true,
CaseSensitive = false
})
// Query documents by metadata (qualified β see AddMetadataIndex)
.AddMetadataIndex(new XdmQName(CatalogNs, "supplier"), XdmValueType.XdmString)
.AddMetadataIndex(new XdmQName(CatalogNs, "importBatch"), XdmValueType.XdmInteger);
});
#Methods
#AddFullTextIndex(String,PhoenixmlDb.Core.FullTextIndexOptions)
Adds a full-text index that enables
ft:contains()
full-text search on text content.
Parameters:
-
pathPatternβ Path to restrict full-text indexing to, ornullto index all text content in the document. For example,"//product/description"indexes only description elements, reducing index size and improving relevance. -
optionsβ Tokenization and text analysis options controlling language, stemming, case sensitivity, and stop words. Whennull,FullTextIndexOptions.Defaultis used (English, stemming enabled, case-insensitive).
Returns: This IndexConfiguration instance for fluent chaining.
Full-text indexes tokenize text content into searchable terms. This enables natural language queries using the ft:contains() function in XQuery, supporting stemming (e.g., "running" matches "run"), case-insensitive matching, and stop word filtering.
#AddMetadataIndex(PhoenixmlDb.Xdm.XdmQName,PhoenixmlDb.Core.XdmValueType)
Adds a metadata index that enables efficient queries by document metadata key-value pairs.
Parameters:
-
metadataNameβ The qualified metadata name to index (case-sensitive). -
valueTypeβ The XDM type for indexing the metadata value. Defaults toXdmValueType.XdmString. Use a numeric type if the metadata values are numbers and you need range queries.
Returns: This IndexConfiguration instance for fluent chaining.
Without a metadata index, IContainer.QueryMetadataAsync``1 must scan all documents' metadata to find matches. A metadata index enables direct lookup by key and value.
The name is qualified because the metadata store keys by qualified name. An index declared for one namespace's status does not answer for another's, and adding an index never changes which documents a query returns β only how fast it finds them.
#AddMetadataIndex``1(PhoenixmlDb.Core.Metadata.MetadataProperty<``0>,PhoenixmlDb.Core.XdmValueType)
Adds a metadata index described by a typed property.
Type parameters:
-
Tβ The property's CLR value type.
Parameters:
-
descriptorβ The metadata property to index. -
valueTypeβ The XDM type to index values under.
Returns: This IndexConfiguration instance for fluent chaining.
Preferred over the
overload where a
already exists: the property is the single place the name and its type are declared, so the index cannot drift from the values it covers.
#AddNameIndex(String)
Adds a name index that speeds up element and attribute name lookups.
Parameters:
-
namespaceUriβ Namespace URI to restrict the index to, ornullto index names in all namespaces. Passnull(the default) unless you want to limit indexing to a specific namespace for storage efficiency.
Returns: This IndexConfiguration instance for fluent chaining.
A name index accelerates queries that look up elements or attributes by name, such as //product or //@id. Without a name index, the query engine must scan every node in every document to find matching names.
#AddPathIndex(String)
Adds a path index that speeds up evaluation of path expressions matching the given pattern.
Parameters:
-
pathPatternβ An XPath-like pattern specifying which paths to index. Supported syntax:/(child axis),//(descendant-or-self axis),@(attribute axis),*(wildcard). Examples:"//customer/address","/root/item/@id","//order/*/price".
Returns: This IndexConfiguration instance for fluent chaining.
A path index pre-computes which documents contain nodes matching the specified path, enabling the query engine to skip documents that cannot possibly match. This is the most commonly used index type for structural XQuery queries.
#AddValueIndex(String,PhoenixmlDb.Core.XdmValueType,String)
Adds a value index that enables typed comparisons and range queries on element or attribute values at the specified path.
Parameters:
-
pathPatternβ Path to the element or attribute whose values should be indexed. -
valueTypeβ The XDM type to use when indexing values. The value at the path is cast to this type for storage in the index. For example, useXdmValueType.XdmDecimalfor monetary values orXdmValueType.Datefor dates. -
collationβ Collation URI for string ordering. Whennull(the default), binary (codepoint) comparison is used. Specify a collation for locale-aware string sorting.
Returns: This IndexConfiguration instance for fluent chaining.
A value index stores the typed value of each matching node, enabling the query engine to evaluate predicates like //product[price > 50] or //order[date > xs:date('2024-01-01')] using an index lookup instead of scanning and parsing every document.
The valueType must match the type used in the query predicate. Indexing a price as XdmValueType.XdmString will not help a numeric comparison query.
#EnableStructuralIndex(Boolean)
Enables or disables structural indexing for parent-child axis navigation. Enabled by default.
Parameters:
-
enabledβtrueto enable (the default),falseto disable.
Returns: This IndexConfiguration instance for fluent chaining.
The structural index maintains parent-child and sibling relationships between nodes, enabling efficient evaluation of axis steps like child::, parent::, following-sibling::, and descendant::. It is enabled by default because most XQuery expressions use structural navigation.
Disabling the structural index reduces storage overhead and write latency for containers where documents are only accessed by name (no XQuery navigation), but this is uncommon.