Code Indexes
A Custom Code Index runs C# you author against nodes in the graph, producing derived text, embeddings, or graph edges that the workspace's standard indexes then consume. Unlike a built-in index (Lucene, HNSW, time, geo), a code index is open-ended: you can call AI providers, run another query, transform fields, or pull in external data — anything you can express in C#.
Code indexes are configured under Manage → Indexes → Code Indexes in the admin UI. This section is the reference for what you can do inside the code, not the UI walkthrough.
For the full catalogue of indexes the workspace supports (Lucene, embeddings, parsers, linkers, filters), see Indexes.
When to use a code index
| Need | Use |
|---|---|
| Generate a derived text field that's a function of multiple properties | Code index producing (uid, derived text) |
| Compute embeddings from an external API and have the workspace index them | Code index producing (uid, float[]) |
Run an LLM extractor that writes back entities + Mentions edges |
Code index with side effects via Graph |
| Bulk-load static derived data without runtime work | A data connector — not an index |
| Custom search execution / facet generation at query time | A search execution scope |
A code index is the right tool when the derivation needs to rerun automatically whenever the source node changes. If you only need to compute the field once at ingest time, do it in the connector.
In this section
- Execution scope — variables and methods (
Graph,Q(),ToIndex,ChatAI, …) available inside the code-index body.
Lifecycle
The worker batches nodes (ToIndex is the list of UIDs in the current batch) and invokes your body. Whatever you yield return flows into the workspace's index. Side effects via Graph (adding nodes, linking edges) are committed automatically when the batch finishes.
Patterns
Derived text for embedding:
foreach (var uid in ToIndex)
{
var node = Graph.Get(uid);
var summary = node.GetString(N.SupportCase.Summary);
var content = node.GetString(N.SupportCase.Content);
yield return (uid, $"{summary}\n{content}");
}
LLM extraction with side effects:
foreach (var uid in ToIndex)
{
var node = Graph.Get(uid);
var text = node.GetString(N.Article.Body);
var people = await ChatAI.ExtractAsync<string[]>(
prompt: "Extract person names as JSON array",
input: text,
cancellationToken: CancellationToken);
foreach (var name in people ?? Array.Empty<string>())
{
var person = Graph.TryAdd(new Person { Name = name });
Graph.Link(node, person, "Mentions", "MentionedIn");
}
}
The ChatAI helper uses whichever provider is configured under Settings → AI.
See also
- Execution scope reference
- Indexes overview — all index types, not just code
- Search execution scopes — sibling concept for query-time code
- Data connectors — when the derivation belongs at ingest time, not as an index