Améliorations au moteur de recherche

This commit is contained in:
François Pelletier 2024-11-30 22:03:49 -05:00
parent 15eb318212
commit fc6bd9f255
21 changed files with 509 additions and 223 deletions

View file

@ -0,0 +1,25 @@
import subprocess
import os
def run_streamlit_app():
# Obtenir le chemin du répertoire courant
current_dir = os.path.dirname(os.path.abspath(__file__))
# Construire le chemin vers streamlit_app.py
app_path = os.path.join(current_dir, 'streamlit_app.py')
# Commande pour exécuter l'application Streamlit
command = f"streamlit run {app_path}"
try:
# Exécuter la commande
subprocess.run(command, shell=True, check=True)
except subprocess.CalledProcessError as e:
print(f"Erreur lors du lancement de l'application Streamlit : {e}")
except Exception as e:
print(f"Une erreur inattendue s'est produite : {e}")
if __name__ == "__main__":
run_streamlit_app()

View file

@ -77,12 +77,15 @@ client = typesense.Client({
'connection_timeout_seconds': 2
})
def rechercher_documents(cette_requete, ces_filtres=None, facette_par=None):
parametres_recherche = {
'q': cette_requete,
'query_by': 'texte',
'sort_by': 'creation_timestamp:desc',
'per_page': 100,
'query_by': 'texte,embedding',
'sort_by': '_text_match(buckets: 10):desc,creation_timestamp:desc',
"exclude_fields": "embedding",
"prefix": "false",
'per_page': 10,
'page': 1
}
@ -92,31 +95,72 @@ def rechercher_documents(cette_requete, ces_filtres=None, facette_par=None):
if facette_par:
parametres_recherche['facet_by'] = facette_par
all_results = []
while True:
results = client.collections['social_media_posts'].documents.search(parametres_recherche)
all_results.extend(results['hits'])
if len(all_results) >= results['found']:
break
parametres_recherche['page'] += 1
st.write("Search parameters:", parametres_recherche)
all_results = []
try:
while True:
results = client.collections['social_media_posts'].documents.search(parametres_recherche)
all_results.extend(results['hits'])
if len(all_results) >= results['found']:
break
parametres_recherche['page'] += 1
results['hits'] = all_results
return results
except Exception as e:
st.error(f"Error during search: {str(e)}") # Error handling
# Récupérer dynamiquement les réseaux depuis Typesense
def get_networks():
search_parameters = {
'q': '*',
'query_by': 'network',
'facet_by': 'network',
'per_page': 0
}
try:
results = client.collections['social_media_posts'].documents.search(search_parameters)
networks = [facet['value'] for facet in results['facet_counts'][0]['counts']]
return networks
except Exception as e:
st.error(f"Erreur lors de la récupération des réseaux : {str(e)}")
return ['Facebook', 'Instagram', 'Threads', 'LinkedIn', 'WordPress'] # Valeurs par défaut en cas d'erreur
results['hits'] = all_results
return results
# Interface utilisateur Streamlit
st.title('Recherche dans tes contenus publiés sur le web')
# Indiquer le nombre total de documents indexés dans Typesense
collections = client.collections.retrieve()
total_documents = sum(collection['num_documents'] for collection in collections)
st.write(f"Total documents indexés: {total_documents}")
# Champ de recherche
requete = st.text_input('Entrez votre requête de recherche')
# Filtre de plage de dates
col1, col2 = st.columns(2)
date_debut = col1.date_input('Date de début')
date_fin = col2.date_input('Date de fin')
date_debut = col1.date_input('Date de début', value=datetime.now() - pd.DateOffset(years=1))
date_fin = col2.date_input('Date de fin', value=datetime.now())
# Filtre de réseau social
reseaux = ['Facebook', 'Instagram', 'Threads' ,'LinkedIn', 'WordPress']
reseaux_selectionnes = st.multiselect('Sélectionnez les réseaux sociaux', reseaux)
reseaux = get_networks()
reseaux_selectionnes = st.multiselect('Sélectionnez les réseaux sociaux', reseaux,
default=reseaux[0] if reseaux else None)
# Filtre de langue
langues = [('fr', 'Français'), ('en', 'English')]
langue_selectionnees = st.multiselect('Sélectionnez la langue',
options=[label for code, label in langues],
format_func=lambda x: x,
default='Français')
# Convertir les étiquettes en codes de langage
selected_lang_codes = [code for code, label in langues if label in langue_selectionnees]
if st.button('Rechercher'):
# Préparer les filtres
@ -124,8 +168,9 @@ if st.button('Rechercher'):
fin_datetime = datetime.combine(date_fin, time.max)
filtre_date = f"creation_timestamp:[{int(debut_datetime.timestamp())}..{int(fin_datetime.timestamp())}]"
filtre_reseau = f"network:[{' '.join(reseaux_selectionnes)}]" if reseaux_selectionnes else None
filtre_langue = f"langue:[{' '.join(selected_lang_codes)}]" if selected_lang_codes else None
filtres = ' && '.join(filter(None, [filtre_date, filtre_reseau]))
filtres = ' && '.join(filter(None, [filtre_date, filtre_reseau, filtre_langue]))
# Effectuer la recherche pour tous les résultats
tous_resultats = rechercher_documents(requete, ces_filtres=filtres, facette_par='network')
@ -133,14 +178,44 @@ if st.button('Rechercher'):
# Afficher le nombre total de résultats
st.subheader(f"Trouvé {nombre_total_resultats} résultats")
# Affichage des résultats (100 maximum)
st.subheader("Résultats de la recherche")
for hit in tous_resultats['hits'][:100]: # Limite à 100 résultats
col1, col2 = st.columns([1, 4])
with col1:
st.markdown(f"**{hit['document']['network']}**")
st.markdown(
f"**{datetime.fromtimestamp(hit['document']['creation_timestamp']).strftime('%Y-%m-%d %H:%M:%S')}**")
# Étiquettes de couleur pour les facettes
st.markdown(f"""
<span style="background-color: #007bff; color: white; padding: 2px 6px; border-radius: 10px;">
{hit['document']['langue']}
</span>
""", unsafe_allow_html=True)
with col2:
# Boîte de texte pour le contenu
st.text_area("Contenu", hit['document']['texte'], height=150)
# URI en dessous
if 'uri' in hit['document']:
st.markdown(f"[Lien vers le post original]({hit['document']['uri']})")
st.markdown("---")
# Afficher les facettes
if 'facet_counts' in tous_resultats:
facettes_reseau = {facette['value']: facette['count'] for facette in tous_resultats['facet_counts'][0]['counts']}
facettes_reseau = {facette['value']: facette['count'] for facette in
tous_resultats['facet_counts'][0]['counts']}
st.subheader("Résultats par Réseau")
# Graphique en camembert pour montrer la distribution des résultats par réseau social
fig = px.pie(values=list(facettes_reseau.values()), names=list(facettes_reseau.keys()), title="Distribution par Réseau")
fig = px.pie(values=list(facettes_reseau.values()), names=list(facettes_reseau.keys()),
title="Distribution par Réseau")
# Ce graphique montre la proportion de résultats pour chaque réseau social
st.plotly_chart(fig)
@ -180,21 +255,3 @@ if st.button('Rechercher'):
df_pivot['mois'] = df_pivot['mois'].dt.strftime('%B %Y')
# Ce tableau fournit un résumé détaillé du nombre de posts par réseau social pour chaque mois
st.dataframe(df_pivot)
# Créer une chaîne pour contenir tous les résultats
all_results_text = ""
# Peupler la chaîne avec tous les résultats
for hit in tous_resultats['hits']:
horodatage = hit['document']['creation_timestamp']
all_results_text += f"**{hit['document']['network']}** - {datetime.fromtimestamp(horodatage).strftime('%Y-%m-%d %H:%M:%S')}\n\n"
paragraphes = hit['document']['texte'].split('\n')
for paragraphe in paragraphes:
if paragraphe.strip():
all_results_text += f"{paragraphe}\n\n"
all_results_text += "---\n\n"
# Afficher les résultats dans une zone de texte
st.text_area("Résultats de la recherche", all_results_text, height=400)