Skip to content

feat(find): index column names + semantic_type in dataset search - #95

Merged
Gabrymi93 merged 2 commits into
mainfrom
feat/find-index-columns
Oct 15, 2026
Merged

Gabrymi93 merged 2 commits into
mainfrom
feat/find-index-columns

Conversation

@Gabrymi93

Copy link
Copy Markdown
Member

Sintesi

find() non scorreva le colonne del dataset, nonostante il topic_index porti già ~6.200 definizioni di colonna con name/role/semantic_type/description. Una query che matchava solo un nome colonna o un semantic_type restituiva 0 risultati.

Le colonne ora sono un campo scorato: nomi+descrizioni come testo di scoperta, semantic_type come tag strutturato. Query come find("cig") o find("codice_fiscale") ora trovano anac_aggiudicatari (colonne cig→cig_code, codice_fiscale→fiscal_code) che prima uscivano solo se quei termini comparivano in slug/name/description/tags.

Contesto collegato

Livello A della valutazione complessità/ROI ricerca. Livello B (arricchire semantic_type vuoti nei cataloghi) e C (estrazione valori distinti) fuori scope — C in particolare duplicherebbe il ruolo di toolkit_query.

Cosa cambia

  • Modifica builder (src/) — navigation.py:search_index
  • Bug fix (campo non scorato)
  • Documentazione

Dettaglio

  • Nuovo helper _columns_index_text(columns) → (names+descs, semantic_types)
  • search_index: merge delle entry full aggiunge columns; scoring dataset aggiunge (col_text, "text") e (col_sem, "tag")
  • by_slug intoccato (le colonne restano solo nelle entry full, che sono la fonte primaria)

Impatto su artifact upstream

  • Nessun impatto su artifact — query-time change su dati già presenti nel topic_index

Verifica

pytest tests/          # 58 passed
ruff check src tests   # ok
mypy src/              # ok

Smoke su artifact CI reale

Query Prima Dopo
cig 0 hit su anac_aggiudicatari (colonna cig) anac_aggiudicatari score 35
codice_fiscale 0 hit su anac_aggiudicatari anac_aggiudicatari score 35
appalti pubblici ANAC / bandi di gara / negativi invariati invariati

Rank 35 (text) vs 80 (slug) per i match su colonna: corretto, un match su schema vale meno di un match su slug.

Checklist PR

  • Perimetro stretto: una PR = un campo scorato
  • Issue collegata o motivazione dell'assenza (sessione valutazione complessità/ROI)

Note per chi revisiona

  • Il fixture di test ha columns su anac_bandi_gara per coprire nome colonna (importo) e semantic_type (cig); le entry senza colonne degradano graceful a 0 nel campo.
  • Se un giorno servirà cercare valori distinti delle dimensioni (es. "Lombardia"), quello è toolkit_query (SQL), non find — non si duplica qui.

The topic_index already carries full column defs (~6.2k across the Lab)
with name, role, semantic_type, description — but find() never scored
them, so a query matching only a column name/type returned nothing.

Columns are now a scored field on datasets (col name+desc as text,
semantic_type as tag), unlocking queries like:
  find("cig")            → anac_aggiudicatari (cig_code column)
  find("codice_fiscale") → anac_aggiudicatari (fiscal_code column)

No new pipeline, no artifact growth — pure query-time change on data
already present. Level A only; distinct-value extraction (level C) is
explicitly out of scope, that's toolkit_query's job.
Profiling showed 95% of search_index time in matching, dominated by
_deaccent (unicodedata.normalize + combining per char) re-running on
every field of every entity for every query — even pure-ASCII fields.

- _deaccent: skip normalize when text.isascii() (~99% of Lab fields)
- _field_words: optional per-search word_cache keyed by field value;
  search_index threads one shared dict so identical values (source_id,
  category, registry_source repeated across datasets) tokenize once
- _score_entity: precompute token forms once, tokenize each field once
  per entity (was once per token×field); drop the double _field_words
  call in the prepared listcomp

Wall-clock on real CI artifact (436 datasets, 10-entity limit):
~150ms → ~70ms per query. _field_words calls 173k → 97k (cache hits
are dict lookups), _deaccent 173k → 63k (rest are ascii no-ops).

Behavior unchanged — same scores, same hits on all regression queries.
@Gabrymi93
Gabrymi93 merged commit 04f0c10 into main Oct 15, 2026
2 checks passed
@Gabrymi93
Gabrymi93 deleted the feat/find-index-columns branch October 15, 2026 19:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant