Name matching
How a name becomes a record: the score the resolver gives each spelling it knows, when it answers, when it says the name is ambiguous, and the order search results come back in.
The resolver's score
The resolver holds every spelling it knows for each firearm: its id, its name, the alternate names its record lists, and spellings derived from them. A query is split into words, every run of adjacent words is looked up, and each firearm is scored by the widest run that names it.
wobei
- The characters the matched run covers, and the characters in the whole query, spaces and punctuation left out. A run that covers the whole query scores its full weight.
- How far a spelling of that kind is trusted, from the table below.
- The spelling's own confidence: 1 for a spelling a record states, lower for one the resolver derived with less certainty.
| Spelling | Weight | What it is |
|---|---|---|
slug | 1.00 | The record's id |
name | 1.00 | The record's name |
alternate | 0.95 | A name the record lists, or a spelling of one with its punctuation normalised |
shorthand | 0.85 | A shorthand derived from the name, such as the model without its maker |
base | 0.70 | The name with a variant's tail removed (Gen5, Mk II, A2), which is how "Glock 19" finds the generations |
family | 0.50 | The leading designation several variants share, weaker than a base so an exact stem wins over its variants |
When it answers
- Resolved: the best score is at least 0.45 and no other firearm is within 0.02 of it. The answer names the firearm, the words it matched and the words it did not.
- Ambiguous: two or more firearms score within 0.02 of the best. None is chosen; up to 5 are returned to choose between.
- Not found, with suggestions: the best score is below 0.45, which means most of the query was words the resolver did not recognise. Up to 5 of the best are returned as suggestions.
- Not found: no spelling matched at all. The longest word, if it has three characters or more, is looked up as part of any name, and what that finds is returned as suggestions with a score of 0.
The order of search results
Search puts what the name says before what the text says. Results fall into four tiers, and relevance orders them within each.
- The name starts with what was typed, as typed or with its spaces and hyphens removed. A whole word comes before part of one, then the shorter name, so the base model comes before its variants.
- The name or an alternate name holds every word as typed, or two typed words as the one designation they spell.
- The same, once letters are split from digits, so "ak47" finds "AK 47".
- Everything else: the words matched the maker, a caliber, the category or the description.
Within a tier, results are ranked by the BM25 relevance of the full text index, with each column's matches weighted as below: a word in the name counts ten times one in the description.
| Where the words matched | Weight |
|---|---|
| Name | 10 |
| Alternate names | 8 |
| Maker | 4 |
| Calibers | 2 |
| Category | 2 |
| Description | 1 |
Worked example: "Glock 19"
"Glock 19" splits into glock, 19, 7 characters, and its widest run, "glock19", covers all 7. Four records answer to it. glock-g19 lists "Glock 19" among its alternate names: s = 7/7 × 0.95 × 1 = 0.95. Each of glock-19-gen4, glock-19-gen5, glock-19-gen6 matches by its base spelling, its name with the Gen tail removed: s = 7/7 × 0.7 × 1 = 0.70. The best clears 0.45 and nothing is within 0.02 of it, so the query resolves to glock-g19 and returns the three generations as alternatives.
That is the kind weights at work: a name a record states outranks one the resolver derived, however well the derived one fits. "Glock 19 Gen5" matches that record's own name at a weight of 1 and resolves to it outright.