2. Natural language search fundamentals
An engineer who has just finished a frontal impact simulation rarely wants to browse a folder tree. What they actually want to type is something like "pedestrian head impact cases from 2023 where the hood deformed more than 40 mm" and get a ranked list of matching runs. Turning that sentence into a precise archive query is the job of a natural language search layer. This chapter explains the three cooperating stages that make it work: query understanding, semantic parsing, and retrieval.
Why keyword search breaks on simulation archives
Crash simulation archives are not document collections. A single run directory typically contains a solver deck (main.key), a result file (d3plot), a run log, a material database reference, and metadata such as load case, vehicle program, occupant or pedestrian subsystem, and solver version. The vocabulary is dense and abbreviation-heavy: ODB, HIC, IP, B-pillar, THOR, LS-DYNA, PAM-CRASH. A keyword index over filenames will match the literal token "hood" only if someone named a file that way. It cannot connect "hood" to engine_hood, bonnet, or a part ID such as 5001234.
Three failure modes appear repeatedly:
- Lexical mismatch. The user's word and the archive's word differ, even though they mean the same component.
- Unstated constraints. "Recent" or "high severity" carry no literal token but imply a filter on date or on a physical quantity.
- Aggregation intent. "Which configuration gives the lowest HIC?" is not a lookup; it is a comparison across many runs.
Stage 1 — Query understanding
Query understanding converts the raw string into a structured intent. It performs four operations in sequence.
Normalization lowercases text, expands known abbreviations from a domain lexicon, and repairs common typos. A lexicon entry might map hic → head_injury_criterion, bonnet → hood, and ped → pedestrian.
Tokenization and entity recognition tags spans with types. In the example query, the recognizer should label pedestrian head impact as a load case, 2023 as a time constraint, hood as a component, and 40 mm as a measurement threshold.
Intent classification decides whether the user wants a filtered list, a single best run, a trend, or a comparison. This determines the downstream query shape.
Slot filling assembles the recognized entities into a typed frame. The frame is the contract between understanding and parsing.
intent: list_runs
load_case: pedestrian_head_impact
year: {gte: 2023, lte: 2023}
component: hood
metric: max_deformation
operator: gt
value: 40
unit: mm
sort: relevance
Stage 2 — Semantic parsing
Semantic parsing maps the frame onto the archive's actual schema. This is where most engineering-specific difficulty lives, because the schema is heterogeneous. Some fields are structured columns in a run database; others are buried inside solver decks or must be computed from result files.
Parsing resolves three kinds of ambiguity:
- Ontology mapping. The user says "hood"; the archive stores part group
HOOD_ASSYwith child parts5001234and5001235. The parser expands the component slot to that part set. - Metric binding. "Deformed more than 40 mm" must bind to a concrete extraction: maximum nodal displacement of the hood part set over the full time history, in the global Z direction, taken from
d3plot. The parser records the extraction recipe, not just the metric name. - Unit and reference consistency. If the archive stores displacement in meters, the parser converts 40 mm to 0.04 m. If the sign convention is that positive Z is upward, a downward hood deformation is negative, so "more than 40 mm" must be interpreted as magnitude. This convention must be stated once and applied consistently.
Stage 3 — Retrieval models
Once the query is parsed, retrieval ranks candidate runs. Three model families are useful, and production systems usually combine them.
| Model | Mechanism | Strength | Weakness |
|---|---|---|---|
| Lexical (BM25) | Term frequency over tokenized metadata and deck comments | Exact part IDs, solver names, file paths | Fails on paraphrase and synonyms |
| Vector / dense | Embedding similarity between query and run description | Handles paraphrase and conceptual similarity | Weak on rare identifiers; needs a trained encoder |
| Structured filter | Predicate evaluation on parsed slots | Exact numeric and date constraints | Requires clean, populated metadata |
A practical pipeline runs the structured filter first to reduce the candidate set, then applies lexical and dense scoring to rank the survivors, and finally fuses the two scores. A simple and effective fusion is reciprocal rank fusion:
score(run) = Σ_over_rankers 1 / (k + rank_ranker(run))
# k = 60 is a common default
For the example query, the structured filter keeps only 2023 pedestrian head impact runs whose hood part set exists in the model. Lexical scoring boosts runs whose metadata mentions hood or bonnet. Dense scoring boosts runs whose description reads like a pedestrian protection study. The fused list is what the engineer sees.
Putting the stages together
What to verify when results look wrong
Debugging a natural language search layer is easier if you inspect each stage independently. Print the parsed frame first. If the frame is wrong, the problem is in understanding or parsing, not retrieval. If the frame is right but the ranking is poor, the problem is in scoring or in metadata coverage.
Common symptoms and their usual causes:
- Zero results for a query you know should match. The structured filter is too strict — often a unit mismatch (40 mm vs 0.04 m) or a part-set name that does not exist in older models.
- Relevant runs ranked below irrelevant ones. Dense embeddings are dominating; increase the lexical weight or add the part ID as a required term.
- Consistently missing one load case. The ontology lacks a synonym mapping, so the user's phrasing never reaches the archive's label.
- Numeric thresholds ignored. The metric slot bound to a name but not to an extraction recipe, so the filter silently passed everything.
The three stages form a contract: understanding produces a frame, parsing turns the frame into an executable plan against the archive schema, and retrieval ranks runs using a combination of exact filters and similarity scoring. Keeping the contract explicit — and auditable — is what makes natural language search trustworthy enough for engineering decisions rather than a demo.