Tutoriel 1 : Créer une application de recherche simple avec Cortex Search¶
Introduction¶
Ce tutoriel décrit comment démarrer avec Cortex Search pour une application de recherche simple.
Ce que vous apprendrez¶
Créez un Cortex Search Service à partir d’un ensemble de données d’annonces AirBnb.
Créer une application Streamlit in Snowflake qui vous permet d’interroger votre Cortex Search Service.
Conditions préalables¶
Les prérequis suivants sont nécessaires à la réalisation de ce tutoriel :
Vous disposez d’un compte Snowflake et d’un utilisateur avec un rôle qui accorde les privilèges nécessaires pour créer une base de données, des tables, des objets d’entrepôt virtuel, des Cortex Search Services et des applications Streamlit.
Consultez les Snowflake en 20 minutes pour obtenir des instructions afin de répondre à ces exigences.
Étape 1 : Configuration¶
Obtenir les données d’échantillon¶
Vous utiliserez un exemple d’ensemble de données hébergé sur Huggingface, téléchargé en un seul fichier JSON. Téléchargez le fichier directement depuis votre navigateur en suivant ce lien :
Note
Dans un environnement non didactique, vous apporteriez vos propres données, éventuellement déjà présentes dans une table Snowflake.
Création de la base de données, des tables et de l’entrepôt¶
Exécutez les instructions suivantes pour créer une base de données et un entrepôt virtuel nécessaires pour ce tutoriel. Après avoir terminé le tutoriel, vous pouvez détruire ces objets.
CREATE DATABASE IF NOT EXISTS cortex_search_tutorial_db;
CREATE OR REPLACE WAREHOUSE cortex_search_tutorial_wh WITH
WAREHOUSE_SIZE='X-SMALL'
AUTO_SUSPEND = 120
AUTO_RESUME = TRUE
INITIALLY_SUSPENDED=TRUE;
Remarques :
L’instruction
CREATE DATABASE
crée une base de données. La base de données comprend automatiquement un schéma nommé « public ».L’instruction
CREATE WAREHOUSE
crée un entrepôt initialement suspendu. L’instruction définit égalementAUTO_RESUME = true
, qui démarre l’entrepôt automatiquement lorsque vous exécutez des instructions SQL qui nécessitent des ressources de calcul.
Étape 2 : charger les données dans Snowflake¶
Avant de pouvoir créer un service de recherche, vous devez charger les données d’exemple dans Snowflake.
Vous pouvez télécharger l’ensemble de données dans Snowsight ou en utilisant SQL. Pour télécharger dans Snowsight :
Sélectionnez le bouton + Create au-dessus de la barre de navigation de gauche.
Sélectionnez ensuite Table » From File.
Sélectionnez votre entrepôt nouvellement créé comme entrepôt pour votre table dans la liste déroulante située dans le coin supérieur droit.
Faites glisser et déposez le fichier de données JSON dans la boîte de dialogue.
Sélectionnez la base de données que vous avez créée ci-dessus et spécifiez le schéma PUBLIC.
Enfin, spécifiez la création d’une nouvelle table appelée
airbnb_listings
et sélectionnez Next.Dans le dialogue Load Data into Table, effectuez les réglages suivants. Tout d’abord, décochez les colonnes
image_embeddings
,images
, ettext_embeddings
, car celles-ci ne s’appliquent pas à ce tutoriel. Deuxièmement, ajustez le type de données du champamenities
pour qu’il soit de type ARRAY.Une fois ces réglages effectués, sélectionnez Load pour procéder.
Après un bref instant, vous devriez voir une page de confirmation indiquant que les données ont été chargées.
Sélectionnez Query Data pour ouvrir une nouvelle feuille de calcul Snowsight que vous utiliserez à l’étape suivante.
Étape 3 : Créer le service de recherche¶
Créez un service de recherche sur notre nouvelle table en exécutant la commande SQL suivante.
CREATE OR REPLACE CORTEX SEARCH SERVICE cortex_search_tutorial_db.public.airbnb_svc
ON listing_text
ATTRIBUTES room_type, amenities
WAREHOUSE = cortex_search_tutorial_wh
TARGET_LAG = '1 hour'
AS
SELECT
room_type,
amenities,
price,
cancellation_policy,
('Summary\n\n' || summary || '\n\n\nDescription\n\n' || description || '\n\n\nSpace\n\n' || space) as listing_text
FROM
cortex_search_tutorial_db.public.airbnb_listings;
- Décomposons les arguments de cette commande :
Le paramètre
ON
spécifie la colonne sur laquelle les requêtes doivent effectuer la recherche. Dans ce cas, c’est lelisting_text
, qui est généré dans la requête source sous la forme d’une concaténation de plusieurs colonnes de texte dans la table de base.Le paramètre
ATTRIBUTES
spécifie les colonnes sur lesquelles vous pourrez filtrer les résultats de la recherche. Cet exemple concerneroom_type
etamenities
lors de l’envoi de requêtes à la colonnelisting_text
.Les paramètres
WAREHOUSE
etTARGET_LAG
spécifient respectivement l’entrepôt fourni par l’utilisateur et le niveau d’actualisation souhaité du service de recherche. Cet exemple spécifie d’utiliser l’entrepôtcortex_search_tutorial_wh
pour créer l’index et effectuer des actualisations, et pour conserver le service pas plus de'1 hour'
derrière la table sourceAIRBNB_LISTINGS
.Le champ
AS
définit la table source pour le service. Cet exemple concatène plusieurs colonnes de texte de la table d’origine dans la colonne de recherchelisting_text
afin que les requêtes puissent effectuer des recherches sur plusieurs champs.
Étape 4 : Créer une application Streamlit¶
Vous pouvez interroger le service avec le SDK Python (en utilisant le Paquet Python snowflake
). Ce tutoriel montre comment utiliser le SDK Python dans une application Streamlit in Snowflake.
Tout d’abord, assurez-vous que votre rôle global de la Snowsight UI est le même que le rôle utilisé pour créer le service à l’étape de création du service.
Connectez-vous à Snowsight.
Sélectionnez Projects » Streamlit dans le menu de navigation de gauche.
Sélectionnez + Streamlit App.
Important : Sélectionnez la base de données
cortex_search_tutorial_db
et le schémapublic
pour l’emplacement de l’application.Dans le volet gauche de l’éditeur Streamlit in Snowflake, sélectionnez Packages et ajoutez
snowflake
(version> = 0.8.0) pour installer le paquet dans votre application.Remplacez l’exemple de code d’application par l’application Streamlit suivante :
# Import python packages import streamlit as st from snowflake.core import Root from snowflake.snowpark.context import get_active_session # Constants DB = "cortex_search_tutorial_db" SCHEMA = "public" SERVICE = "airbnb_svc" BASE_TABLE = "cortex_search_tutorial_db.public.airbnb_listings" ARRAY_ATTRIBUTES = {"AMENITIES"} def get_column_specification(): """ Returns the name of the search column and a list of the names of the attribute columns for the provided cortex search service """ session = get_active_session() search_service_result = session.sql(f"DESC CORTEX SEARCH SERVICE {DB}.{SCHEMA}.{SERVICE}").collect()[0] st.session_state.attribute_columns = search_service_result.attribute_columns.split(",") st.session_state.search_column = search_service_result.search_column st.session_state.columns = search_service_result.columns.split(",") def init_layout(): st.title("Cortex AI Search") st.markdown(f"Querying service: `{DB}.{SCHEMA}.{SERVICE}`".replace('"', '')) def query_cortex_search_service(query, filter={}): """ Queries the cortex search service in the session state and returns a list of results """ session = get_active_session() cortex_search_service = ( Root(session) .databases[DB] .schemas[SCHEMA] .cortex_search_services[SERVICE] ) context_documents = cortex_search_service.search( query, columns=st.session_state.columns, filter=filter, limit=st.session_state.limit) return context_documents.results @st.cache_data def distinct_values_for_attribute(col_name, is_array_attribute=False): session = get_active_session() if is_array_attribute: values = session.sql(f''' SELECT DISTINCT value FROM {BASE_TABLE}, LATERAL FLATTEN(input => {col_name}) ''').collect() else: values = session.sql(f"SELECT DISTINCT {col_name} AS VALUE FROM {BASE_TABLE}").collect() return [ x["VALUE"].replace('"', "") for x in values ] def init_search_input(): st.session_state.query = st.text_input("Query") def init_limit_input(): st.session_state.limit = st.number_input("Limit", min_value=1, value=5) def init_attribute_selection(): st.session_state.attributes = {} for col in st.session_state.attribute_columns: is_multiselect = col in ARRAY_ATTRIBUTES st.session_state.attributes[col] = st.multiselect( col, distinct_values_for_attribute(col, is_array_attribute=is_multiselect) ) def display_search_results(results): """ Display the search results in the UI """ st.subheader("Search results") for i, result in enumerate(results): result = dict(result) container = st.expander(f"[Result {i+1}]", expanded=True) # Add the result text. container.markdown(result[st.session_state.search_column]) # Add the attributes. for column, column_value in sorted(result.items()): if column == st.session_state.search_column: continue container.markdown(f"**{column}**: {column_value}") def create_filter_object(attributes): """ Create a filter object for the search query """ and_clauses = [] for column, column_values in attributes.items(): if len(column_values) == 0: continue if column in ARRAY_ATTRIBUTES: for attr_value in column_values: and_clauses.append({"@contains": { column: attr_value }}) else: or_clauses = [{"@eq": {column: attr_value}} for attr_value in column_values] and_clauses.append({"@or": or_clauses }) return {"@and": and_clauses} if and_clauses else {} def main(): init_layout() get_column_specification() init_attribute_selection() init_limit_input() init_search_input() if not st.session_state.query: return results = query_cortex_search_service( st.session_state.query, filter = create_filter_object(st.session_state.attributes) ) display_search_results(results) if __name__ == "__main__": st.set_page_config(page_title="Cortex AI Search and Summary", layout="wide") main()
Voici une brève description des principaux composants du code Streamlit-in-Snowflake ci-dessus :
get_column_specification
utilise une requête DESCRIBE SQL pour obtenir des informations sur les attributs disponibles dans le service de recherche et les stocke dans l’état de Streamlit.init_layout
définit l’en-tête et l’introduction de la page.query_cortex_search_service
gère la requête du Cortex Search Service via la bibliothèque client Python.create_filter_object
traite les attributs de filtre sélectionnés à partir de la forme Streamlit dans les objets appropriés à utiliser par la bibliothèque Python pour interroger Cortex Search.distinct_values_for_attribute
détermine quelles valeurs sont possibles pour chaque attribut filtrable pour remplir les menus déroulants.init_search_input
,init_limit_input
,init_attribute_selection
initialisent les entrées pour la requête de recherche, la limite du nombre de résultats et les filtres d’attributs.display_search_results
formate les résultats de la recherche en éléments Markdown affichés dans la page de résultats.
Étape 5 : Nettoyer¶
Nettoyer (facultatif)¶
Exécutez les commandes DROP <objet> suivantes pour remettre votre système dans son état initial avant de commencer le tutoriel :
DROP DATABASE IF EXISTS cortex_search_tutorial_db;
DROP WAREHOUSE IF EXISTS cortex_search_tutorial_wh;
Détruire la base de données supprime automatiquement toutes les objets de base de données liés, par exemple les tables.
Prochaines étapes¶
Félicitations ! Vous avez réussi à créer une application de recherche simple sur des données textuelles dans Snowflake. Vous pouvez passer à Tutoriel 2 pour voir comment superposer les Fonctions LLM Cortex pour construire un chatbot AI avec Cortex Search.
Ressources supplémentaires¶
De plus, vous pouvez poursuivre l’entraînement en utilisant les ressources suivantes :