Summary#
Some tokens carry meaning no amount of language understanding can recover: ORD-004471, AB1234X, 000346. A
search engine that only understands meaning cannot find them reliably, so the platform also matches such tokens
EXACTLY, and weights that match heavily — but only when it is confident the query contains one.
Left alone it decides by shape: a token with a digit and at least four characters. That works, and it is a guess
about your data. app.Memory lets you state the shapes instead.
Signature#
app.Memory = new MemoryConfig {
Identifiers = [ @"ORD-\d{6}", @"[A-Z]{2}\d{4}[A-Z]" ]
};Description#
Each entry is a regular expression. A query is scanned for them, and anything found is matched exactly against the corpus alongside the ordinary meaning-based search.
Declaring turns the built-in guessing OFF. You have answered the question the guess was standing in for, and running both would put the guesses back on exactly the queries your patterns did not match — the ones you have implicitly said contain no identifier.
That matters because the shape guess is not perfect on real language. Measured against a public benchmark, it fired
on 6 of 470 questions and five of those were not identifiers at all — 15th, 10th, 5-day, pre-1920. Those
now abstain, but a corpus whose codes look like ordinary numbers is still better served by saying so.
Patterns are checked when you compile. A pattern that is not a valid regular expression is a compile error naming it — not a search that fails later, in production, on the first query that happens to reach it.
They are also checked for SPEED. Patterns run once per query against text a caller supplied, so a pattern that can take exponential time on an unlucky input is refused at compile time rather than becoming a way to stall your app. In practice this rules out backreferences and lookaround; ordinary character classes, quantifiers and anchors are all fine.
Use @"…" for a pattern, as in every example here. Inside @"…" a backslash is just a backslash, which is what a
regular expression is made of.
Removing the declaration puts you back to the built-in behaviour — the stored patterns go with it.
Examples#
using Osyrin.Memory;
entity Order {
[MaxLength(64)] string Reference;
[Searchable(Memory)] string? Notes;
}
app.Memory = new MemoryConfig {
Identifiers = [ @"ORD-\d{6}", @"[A-Z]{3}-\d{4}" ]
};using Osyrin.Memory;
List<SearchHit> Chase(string question) {
// "did we ever sort out the packaging fault on ORD-004471?" matches that order's notes on the token
// itself — not merely on sounding like a packaging complaint.
return Memory.Search(question, limit: 5);
}See also#
- using Memory (semantic search) — the search this configures
- How retrieval works — why an exact token match is treated differently from a meaning match
- per-environment config (app.Config) — the rest of the
app.configuration surface