# Trouve-KA — mapping OpenSearch bilingue # Author: Simon-Pierre Boucher # Contact: contact@spboucher.ai """Mapping et settings de l'index documents. - Analyzers français ET anglais sur les champs texte (bilingue dès le départ). - Filtre de synonymes bilingues (thermopompe ↔ heat pump) appliqué à la recherche seulement : pas de traduction à l'ingestion. - Refresh 1 s : une page indexée est cherchable en ~1 seconde (principe cardinal). """ # Synonymes bilingues de départ — extensibles sans réindexation (search-time) BILINGUAL_SYNONYMS = [ "thermopompe, heat pump", "subvention, grant, subsidy", "emploi, job, employment", "entreprise, company, business", "université, university", "cégep, cegep, college", "garderie, daycare, cpe", "impôt, tax, taxes", "santé, health", "plombier, plumber", "électricien, electrician", "déneigement, snow removal", "assurance, insurance", "logement, housing, apartment", "ville, city, municipalité, municipality", "gouvernement, government", "permis, permit, license, licence", ] INDEX_SETTINGS = { "settings": { "number_of_shards": 1, "number_of_replicas": 0, "refresh_interval": "1s", "analysis": { "filter": { "french_elision": { "type": "elision", "articles_case": True, "articles": ["l", "m", "t", "qu", "n", "s", "j", "d", "c", "jusqu", "quoiqu", "lorsqu", "puisqu"], }, "french_stop": {"type": "stop", "stopwords": "_french_"}, "french_stemmer": {"type": "stemmer", "language": "light_french"}, "english_stop": {"type": "stop", "stopwords": "_english_"}, "english_stemmer": {"type": "stemmer", "language": "light_english"}, "bilingual_synonyms": { "type": "synonym_graph", "lenient": True, "synonyms": BILINGUAL_SYNONYMS, }, }, "analyzer": { "fr_text": { "tokenizer": "standard", "filter": ["french_elision", "lowercase", "asciifolding", "french_stop", "french_stemmer"], }, "fr_search": { "tokenizer": "standard", "filter": ["french_elision", "lowercase", "asciifolding", "bilingual_synonyms", "french_stop", "french_stemmer"], }, "en_text": { "tokenizer": "standard", "filter": ["lowercase", "asciifolding", "english_stop", "english_stemmer"], }, "en_search": { "tokenizer": "standard", "filter": ["lowercase", "asciifolding", "bilingual_synonyms", "english_stop", "english_stemmer"], }, }, }, }, "mappings": { "properties": { "url": {"type": "keyword"}, "canonical_url": {"type": "keyword"}, "domain": {"type": "keyword"}, "title": { "type": "text", "analyzer": "fr_text", "search_analyzer": "fr_search", "fields": {"en": {"type": "text", "analyzer": "en_text", "search_analyzer": "en_search"}}, }, "description": { "type": "text", "analyzer": "fr_text", "search_analyzer": "fr_search", "fields": {"en": {"type": "text", "analyzer": "en_text", "search_analyzer": "en_search"}}, }, "body": { "type": "text", "analyzer": "fr_text", "search_analyzer": "fr_search", "fields": {"en": {"type": "text", "analyzer": "en_text", "search_analyzer": "en_search"}}, }, "headings": { "type": "text", "analyzer": "fr_text", "search_analyzer": "fr_search", "fields": {"en": {"type": "text", "analyzer": "en_text", "search_analyzer": "en_search"}}, }, "language": {"type": "keyword"}, "page_quebec_score": {"type": "float"}, "domain_quebec_score": {"type": "float"}, "locations": {"type": "keyword"}, "organizations": {"type": "keyword"}, "people": {"type": "keyword"}, "categories": {"type": "keyword"}, "published_at": {"type": "date"}, "crawled_at": {"type": "date"}, "authority_score": {"type": "float"}, "freshness_score": {"type": "float"}, "quality_score": {"type": "float"}, "spam_score": {"type": "float"}, # embedding (dense_vector/knn) ajouté à l'étape sémantique (§17.7), # le mapping est extensible sans réindexation pour un nouveau champ. } }, }