Interroger un Cortex Search Service

Lorsque vous créez un Cortex Search Service, le point de terminaison d’une REST API est configuré pour répondre aux requêtes adressées au service. Vous avez trois possibilités pour effectuer une requête auprès d’un Cortex Search Service :

Snowflake Python APIs

Les Cortex Search Services peuvent être interrogés à l’aide de la version 0.8.0 ou ultérieure de Snowflake Python APIs. Consultez Snowflake Python APIs : gestion des objets Snowflake avec Python pour plus d’informations sur le Snowflake Python APIs.

Installez la bibliothèque Snowflake Python APIs.

Tout d’abord, installez la dernière version du paquet Snowflake Python APIs depuis PyPI. Consultez Installez la bibliothèque Snowflake Python APIs. pour obtenir des instructions sur l’installation de ce paquet à partir de PyPI.

pip install snowflake -U
Copy

Se connecter à Snowflake

Connectez-vous à Snowflake en utilisant une Session Snowpark ou une Connection Python Connector et créez un objet Root. Consultez Connexion à Snowflake avec Snowflake Python APIs pour plus d’instructions sur la connexion à Snowflake. L’exemple suivant utilise l’objet de la Session Snowpark et un dictionnaire Python pour la configuration.

import os
from snowflake.core import Root
from snowflake.snowpark import Session

CONNECTION_PARAMETERS = {
    "account": os.environ["snowflake_account_demo"],
    "user": os.environ["snowflake_user_demo"],
    "password": os.environ["snowflake_password_demo"],
    "role": "test_role",
    "database": "test_database",
    "warehouse": "test_warehouse",
    "schema": "test_schema",
}

session = Session.builder.configs(CONNECTION_PARAMETERS).create()
root = Root(session)
Copy

Interroger le service

Interrogez le service en utilisant la syntaxe suivante :

# fetch service
my_service = (root
  .databases["<service_database>"]
  .schemas["<service_schema>"]
  .cortex_search_services["<service_name>"]
)

# query service
resp = my_service.search(
  query="<query>",
  columns=["<col1>", "<col2>"],
  filter={"@eq": {"<column>": "<value>"} },
  limit=5
)
print(resp.to_json())
Copy

Note

Version 0.8.0 ou ultérieure de la bibliothèque Snowflake Python APIs est nécessaire pour interroger un Cortex Search Service.

Rest API

Cortex Search expose un point de terminaison d’API REST dans la suite des APIs REST Snowflake Cortex. Le point de terminaison REST généré pour un Cortex Search Service présente la structure suivante :

https://<account_url>/api/v2/databases/<db_name>/schemas/<schema_name>/cortex-search-services/<service_name>:query
Copy

Où :

  • <account_url> : L’URL de votre compte Snowflake. Consultez Recherche de l’organisation et du nom de compte pour un compte pour savoir comment trouver l’URL de votre compte.

  • <db_name> : Base de données dans laquelle réside le service.

  • <schema_name> : Schéma dans lequel réside le service.

  • <service_name> : Nom du service.

  • :query : La méthode à invoquer sur le service. Dans ce cas, la méthode query.

Pour plus de détails, consultez la référence REST API pour le Cortex Search Service. Ce qui suit décrit les paramètres et la syntaxe de filtre à utiliser lors de l’interrogation du service.

Paramètres

Paramètre

Description

query

Votre requête de recherche, pour rechercher dans la colonne de texte du service.

columns

Une liste de colonnes séparées par des virgules à renvoyer pour chaque résultat pertinent dans la réponse. Ces colonnes doivent être incluses dans la requête source du service.

filter

Un objet de filtre pour filtrer les résultats en fonction des données dans les colonnes ATTRIBUTES. Consultez Syntaxe de filtre.

limit

Nombre maximal de résultats à renvoyer dans la réponse.
La valeur maximale acceptée est 1000.
La valeur par défaut est 10.

Configurer l’authentification de l’API REST

Les APIs REST de Snowflake prennent en charge l’authentification par jeton d’accès programmatique (PATs), l’authentification par paire de clés à l’aide de JSON Web Tokens (JWTs), et OAuth. Pour plus de détails, voir Authentification d”Snowflake REST APIs avec Snowflake.

Exemple d’interrogation du service

Pour effectuer une requête sur le service en utilisant curl:

curl --location https://<ACCOUNT_URL>/api/v2/databases/<DB_NAME>/schemas/<SCHEMA_NAME>/cortex-search-services/<SERVICE_NAME>\:query \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header "Authorization: Bearer $PAT" \
--data '{
  "query": "<search_query>",
  "columns": ["col1", "col2"],
  "filter": <filter>
  "limit": <limit>
}'
Copy

Note

Lors de l’interrogation de la REST API avec une authentification JWT, le rôle par défaut de l’utilisateur est utilisé. Ainsi, le rôle par défaut de l’utilisateur qui interroge le service doit avoir USAGE sur la base de données et le schéma dans lesquels réside le service, et sur le service lui-même. Le rôle d’utilisateur interrogateur n’a pas nécessairement besoin de privilèges sur les données de la requête source. Consultez Rôles utilisateur pour plus de détails sur les rôles des utilisateurs.

Service d’aperçu avec la fonction du système SQL

La fonction SNOWFLAKE.CORTEX.SEARCH_PREVIEW vous permet de prévisualiser les résultats des requêtes individuelles adressées à un Cortex Search Service à partir d’un environnement SQL tel qu’une feuille de calcul ou une cellule de carnet Snowflake. Cette fonction permet de valider rapidement et facilement qu’un service est correctement renseigné et fournit des résultats raisonnables.

Exemple

L’exemple suivant prévisualise le service avec la chaîne de requête preview query et analyse les résultats dans un objet VARIANT.

SELECT PARSE_JSON(
  SNOWFLAKE.CORTEX.SEARCH_PREVIEW(
      'my_search_service',
      '{
         "query": "preview query",
         "columns":[
            "col1",
            "col2"
         ],
         "filter": {"@eq": {"col1": "filter value"} },
         "limit":10
      }'
  )
)['results'] as results;
Copy

Important

  • Cette fonction fonctionne uniquement sur les requêtes de type chaîne littérale. Il n’accepte pas un lot de données texte.

  • Cette fonction nécessite davantage de temps de latence que les fonctions les APIs REST ou Python. Il est conçu à des fins de test/validation uniquement. N’utilisez pas cette fonction pour répondre à des requêtes de recherche dans une application d’utilisateur final exigeant une faible latence.

Syntaxe de filtre

Cortex Search prend en charge le filtrage sur les colonnes ATTRIBUTES spécifiées dans la commande CREATE CORTEX SEARCH SERVICE.

Cortex Search prend en charge quatre opérateurs de recherche :

Ces opérateurs de correspondance peuvent être composés de différents opérateurs logiques :

  • @and

  • @or

  • @not

Les notes d’utilisation suivantes s’appliquent :

  • Les correspondances avec les valeurs NaN (« not a number ») de la requête source sont traitées comme décrit dans Valeurs spéciales.

  • Les valeurs numériques en virgule fixe comportant plus de 19 chiffres (sans compter les zéros non significatifs) ne fonctionnent pas avec @eq, @gte ou @lte et ne seront pas retournées par ces opérateurs (bien qu’elles puissent toujours être retournées par la requête globale avec l’utilisation de @not).

  • TIMESTAMP et DATE acceptent des valeurs sous la forme : YYYY-MM-DD et, pour les dates sensibles au fuseau horaire : YYYY-MM-DD+HH:MM. Si le décalage du fuseau horaire n’est pas spécifié, la date est interprétée en UTC.

Ces opérateurs peuvent être combinés en un seul objet filtre.

Exemple

  • Le filtrage sur les lignes où se trouve une colonne de type chaîne string_col est égal à la valeur value.

    { "@eq": { "string_col": "value" } }
    
    Copy
  • Filtrage sur les lignes où la colonne ARRAY array_col contient de la valeur value.

    { "@contains": { "array_col": "arr_value" } }
    
    Copy
  • Filtrage des lignes dont la colonne NUMERIC numeric_col est comprise entre 10,5 et 12,5 (inclus) :

    { "@and": [
      { "@gte": { "numeric_col": 10.5 } },
      { "@lte": { "numeric_col": 12.5 } }
    ]}
    
    Copy
  • Filtrer les lignes où la colonne TIMESTAMP timestamp_col est comprise entre 2024-11-19 et 2024-12-19 (inclus).

    { "@and": [
      { "@gte": { "timestamp_col": "2024-11-19" } },
      { "@lte": { "timestamp_col": "2024-12-19" } }
    ]}
    
    Copy
  • Composition de filtres avec des opérateurs logiques :

    // Rows where the "array_col" column contains "arr_value" and the "string_col" column equals "value":
    {
        "@and": [
          { "@contains": { "array_col": "arr_value" } },
          { "@eq": { "string_col": "value" } }
        ]
    }
    
    // Rows where the "string_col" column does not equal "value"
    {
      "@not": { "@eq": { "string_col": "value" } }
    }
    
    // Rows where the "array_col" column contains at least one of "val1", "val2", or "val3"
    {
      "@or": [
          { "@contains": { "array_col": "val1" } },
          { "@contains": { "array_col": "val1" } },
          { "@contains": { "array_col": "val1" } }
      ]
    }
    
    Copy

Accroissements numériques et déclins avec le temps

Vous pouvez accroître les résultats de recherche ou y appliquer des déclins avec le temps en fonction de métadonnées numériques ou d’horodatage. Cette fonction est utile lorsque vous disposez de métadonnées structurées (par exemple, des signaux de popularité ou de récence) par résultat qui peuvent aider à déterminer la pertinence des documents au moment de la requête. Vous pouvez spécifier deux catégories de signaux de classement lorsque vous effectuez une requête :

Type

Description

Types de colonnes applicables

Exemples de champs de métadonnées (à titre d’illustration)

Accroissement numérique

Métadonnées numériques qui augmentent les résultats ayant plus d’attention ou d’activité.

Type de données numériques

clicks, likes, comments

Déclin avec le temps

Métadonnées de date ou d’heure qui favorisent des résultats plus récents. L’influence des signaux de récence diminue avec le temps.

Type de données de date et d’heure

created_timestamp, last_opened_timestamp, action_date

Les métadonnées de boost et de décroissance proviennent des colonnes de la table source à partir de laquelle un Cortex Search Service est créé. Vous indiquez les colonnes de métadonnées à utiliser pour l’accroissement ou le déclin lorsque vous effectuez la requête, mais ces colonnes doivent être incluses lors de la création du Cortex Search Service.

Requête auprès d’un service avec des signaux d’accroissement ou de déclin

Lors d’une requête auprès d’un Cortex Search Service, indiquez les colonnes à utiliser pour l’accroissement ou le déclin dans les champs facultatifs numeric_boosts et time_decays dans le champ scoring_config.functions. Vous pouvez également spécifier le poids de chaque accroissement ou déclin.

{
  "scoring_config": {
    "functions": {
      "numeric_boosts": [
        {
          "column": "<column_name>",
          "weight": <weight>
        },
        // ...
      ],
      "time_decays": [
        {
          "column": "<column_name>",
          "weight": <weight>,
          "limit_hours": <limit_hours>
        },
        // ...
      ]
    }
  }
}
Copy

Propriétés :

  • numeric_boosts (tableau, facultatif) :

    • <numeric_boost_object> (objet, facultatif) :

      • column_name (string) : Spécifie la colonne numérique à laquelle l’accroissement doit être appliqué.

      • weight (flottant) : Spécifie le poids ou l’importance attribué à la colonne avec accroissement dans le processus de classement. Lorsque plusieurs colonnes sont spécifiées, un poids plus élevé augmente l’influence du champ.

  • time_decays (tableau, facultatif) :

    • <time_decay_object> (objet, facultatif) :

      • column_name (string) : Spécifie la colonne de date et d’heure à laquelle le déclin doit être appliquée.

      • weight (flottant) : Spécifie le poids ou l’importance attribué à la colonne avec déclin dans le processus de classement. Lorsque plusieurs colonnes sont spécifiées, un poids plus élevé augmente l’influence du champ.

      • limit_hours (flottant) : Définit la limite à partir de laquelle le temps commence à avoir moins d’effet sur la pertinence ou l’importance du document. Par exemple, une valeur limit_hours de 240 indique que les documents dont l’horodatage est supérieur à 240 heures (10 jours) par rapport à l’horodatage now ne bénéficient pas d’un accroissement significatif, tandis que les documents dont l’horodatage se situe dans les 240 dernières heures doivent bénéficier d’un accroissement plus important.

      • now (chaîne, facultatif) : Horodatage de référence facultatif à partir duquel les déclins sont calculés au format ISO-8601 yyyy-MM-dd'T'HH:mm:ss.SSSXXX. Par exemple, "2025-02-19T14:30:45.123-08:00". La valeur par défaut est l’horodatage actuel si ce n’est pas spécifié.

Note

Les accroissements numériques sont appliqués sous forme de moyennes pondérées aux champs retournés, tandis que les déclins s’appuient sur une fonction logarithmique pour rétrograder les valeurs les moins récentes.

Les poids sont relatifs dans les champs d’accroissement ou de déclin spécifiés. Si un seul champ est fourni dans un tableau boosts ou decays, la valeur de sa pondération n’a pas d’importance.

Si plusieurs champs sont fournis, les pondérations sont appliquées l’une par rapport à l’autre. Un champ ayant un poids de 10, par exemple, affecte deux fois plus le classement de l’enregistrement qu’un champ ayant un poids de 5.

Exemple

Créer des échantillons de données et Cortex Search Service

Cet exemple utilise une table nommée business_documents avec deux colonnes d’horodatage (last_modified, created_timestamp) et deux colonnes entières (likes, columns) qui peuvent être utilisées pour les accroissements et les déclins des résultats de recherche.

CREATE OR REPLACE TABLE business_documents (
    document_contents VARCHAR,
    last_modified_timestamp TIMESTAMP,
    created_timestamp TIMESTAMP,
    likes INT,
    comments INT
);

INSERT INTO business_documents (document_contents, last_modified_timestamp, created_timestamp, likes, comments)
VALUES
    ('Quarterly financial report for Q1 2024: Revenue increased by 15%, with expenses stable. Highlights include strategic investments in marketing and technology.',
     '2024-01-12 10:00:00', '2024-01-10 09:00:00', 10, 20),

    ('IT manual for employees: Instructions for usage of internal technologies, including hardware and software guides and commonly asked tech questions.',
     '2024-02-10 15:00:00', '2024-02-05 14:30:00', 85, 10),

    ('Employee handbook 2024: Updated policies on remote work, health benefits, and company culture initiatives. Includes new guidelines on hybrid working models.',
     '2024-02-10 15:00:00', '2024-02-05 14:30:00', 85, 10),

    ('Marketing strategy document: Target audience segmentation for upcoming product launch. Detailed plans for social media, influencer partnerships, and content creation.',
     '2024-03-15 12:00:00', '2024-03-12 11:15:00', 150, 32),

    ('Product roadmap 2024: Key milestones for tech product development, including the launch of new features, bug fixes, and performance improvements.',
     '2024-04-22 17:30:00', '2024-04-20 16:00:00', 200, 45),

    ('Annual performance review process guidelines: Procedures for managers to conduct employee evaluations, set goals, and provide constructive feedback.',
     '2024-05-02 09:30:00', '2024-05-01 08:45:00', 60, 5);
Copy

Ensuite, créez un Cortex Search Service nommé business_documents_css sur la colonne document_contents de la table business_documents.

CREATE OR REPLACE CORTEX SEARCH SERVICE business_documents_css
    ON document_contents
    WAREHOUSE = <warehouse_name>
    TARGET_LAG = '1 minute'
AS SELECT * FROM business_documents;
Copy

Interroger le service à l’aide d’accroissements numériques

La requête ci-dessous applique des accroissements numériques aux colonnes likes et comments, avec un poids d’accroissement deux fois plus important sur les valeurs de comments par rapport aux valeurs de likes. La requête utilise la fonction SQL SEARCH_PREVIEW pour rechercher « technology ».

SELECT
    index,
    value['DOCUMENT_CONTENTS']::string as DOCUMENT_CONTENTS,
    value['LIKES']::int as LIKES,
    value['COMMENTS']::int as COMMENTS,
FROM TABLE(FLATTEN(PARSE_JSON(SNOWFLAKE.CORTEX.SEARCH_PREVIEW(
    'business_documents_css',
    '{
      "query": "technology",
      "columns": ["DOCUMENT_CONTENTS", "LIKES", "COMMENTS"],
      "scoring_config": {
        "functions": {
          "numeric_boosts": [
            {"column": "comments", "weight": 2},
            {"column": "likes", "weight": 1}
          ]
        }
      }
    }'
))['results'] ))
Copy

Dans les résultats, notez :

  • Avec les accroissements, le document "Product roadmap 2024:..." est le premier résultat en raison de son grand nombre de j’aime et de commentaires, même si sa pertinence par rapport à la requête "technology" est légèrement plus faible

  • Sans aucun accroissement, le premier résultat de la requête est "IT manual for employees:..."

Requête auprès du service à l’aide de déclins dans le temps

La requête suivante applique des déclins dans le temps basés sur la colonne LAST_MODIFIED_TIMESTAMP, où :

  • Les documents présentant des valeurs LAST_MODIFIED_TIMESTAMP plus récentes, par rapport à l’horodatage now, sont accrues

  • Les documents dont la valeur de LAST_MODIFIED_TIMESTAMP est supérieure à 240 heures à compter de l’horodatage now ne bénéficient que d’un faible accroissement

SELECT
  value['DOCUMENT_CONTENTS']::string as DOCUMENT_CONTENTS,
  value['LAST_MODIFIED_TIMESTAMP']::timestamp as LAST_MODIFIED_TIMESTAMP
FROM TABLE(FLATTEN(PARSE_JSON(SNOWFLAKE.CORTEX.SEARCH_PREVIEW(
    'business_documents_css',
    '{
      "query": "technology",
      "columns": ["DOCUMENT_CONTENTS", "LAST_MODIFIED_TIMESTAMP", "CREATED_TIMESTAMP", "LIKES", "COMMENTS"],
      "scoring_config": {
          "functions": {
              "time_decays": [
                {"column": "LAST_MODIFIED_TIMESTAMP", "weight": 1, "limit_hours": 240, "now": "2024-04-23T00:00:00.000-08:00"}
              ]
            }
        }
    }'
))['results'] ));
Copy

Dans les résultats, notez :

  • Avec les déclins, le document "Product roadmap 2024:..." est le premier résultat en raison de sa récence par rapport à l’horodatage now, même s’il a une pertinence légèrement inférieure à la requête "technology"

  • Sans aucun déclin, le premier résultat de la requête est "IT manual for employees:..."

Reclassement

Par défaut, les requêtes adressées à Cortex Search Services exploitent un reclassement sémantique pour améliorer la pertinence des résultats de recherche. Si le reclassement peut sensiblement améliorer la pertinence des résultats, il peut aussi augmenter sensiblement le temps de latence des requêtes. Vous pouvez désactiver le reclassement dans n’importe quelle requête de Cortex Search si vous estimez que l’avantage qualitatif que procure le reclassement peut être sacrifié au profit d’une vitesse de requête plus rapide dans votre cas d’utilisation.

Note

La désactivation du reclassement réduit la latence des requêtes de 100 à 300 ms en moyenne, mais la réduction exacte de la latence, ainsi que l’ampleur de la dégradation de la qualité, varient selon les charges de travail. Évaluez les résultats côte à côte, avec et sans reclassement, avant de décider de le désactiver dans les requêtes.

Requête auprès d’un Cortex Search Service sans le reclasseur

Vous pouvez désactiver le reclasseur pour une requête individuelle au moment de la requête dans le champ scoring_config.reranker au format suivant :

{
  "scoring_config": {
      "reranker": "none"
}
Copy

Propriétés :

  • reranker (chaîne, facultatif) : Paramètre pouvant être défini sur « none » si le reclasseur doit être désactivé. S’il est exclu ou nul, le reclasseur par défaut est utilisé.

Exemples

Requête auprès d’un service de recherche sans le reclasseur (Python)

Le code suivant effectue une requête sur le service sans l’étape de reclassement en utilisant l’API Python :

resp = business_documents_css.search(
  query="technology",
  columns=["DOCUMENT_CONTENTS", "LAST_MODIFIED_TIMESTAMP"],
  limit=5,
  scoring_config={
    "reranker": "none"
  }
)
Copy

Astuce

Pour interroger un service avec le reclasseur, omettez le paramètre "reranker": "none" de l’objet scoring_config, car le reclassement est le comportement par défaut.

Requête auprès d’un service sans reclasseur (SQL)

L’instruction SQL suivante effectue une requête sur le service sans l’étape de reclassement à l’aide de la fonction SEARCH_PREVIEW.

SELECT
    value['DOCUMENT_CONTENTS'], value['LAST_MODIFIED_TIMESTAMP']
FROM TABLE(FLATTEN(PARSE_JSON(SNOWFLAKE.CORTEX.SEARCH_PREVIEW(
    'business_documents_css',
    '{
      "query": "technology",
      "columns": ["DOCUMENT_CONTENTS", "LAST_MODIFIED_TIMESTAMP"],
      "scoring_config": {
        "reranker": "none"
      }
    }'
))['results'] ));
Copy

Exigences en matière de contrôle d’accès

Le rôle qui interroge le Cortex Search Service doit disposer des privilèges suivants pour récupérer les résultats :

Privilège

Objet

USAGE

Le Cortex Search Service

USAGE

La base de données dans laquelle réside le Cortex Search Service

USAGE

Le schéma dans lequel réside le Cortex Search Service

Requête avec les droits du propriétaire

Les services Cortex Search Service effectuent des recherches avec les droits du propriétaire et suivent le même modèle de sécurité que les autres objets Snowflake qui s’exécutent avec les droits du propriétaire.

Plus particulièrement, cela signifie que tout rôle disposant de privilèges suffisants pour interroger un Cortex Search Service peut interroger n’importe quelle donnée indexée par le service, quels que soient les privilèges de ce rôle sur les objets sous-jacents (tels que les tables et les vues) référencés dans la requête source du service.

Par exemple, pour un Cortex Search Service qui référence une table avec des politiques de masquage au niveau des lignes, les utilisateurs effectuant des requêtes sur ce service pourront voir les résultats de la recherche à partir des lignes sur lesquelles le rôle du propriétaire dispose d’une autorisation de lecture, même si le rôle de l’utilisateur effectuant la requête ne peut pas lire ces lignes dans la table source.

Faites preuve de prudence, par exemple, lorsque vous accordez un rôle avec des privilèges USAGE sur un Cortex Search Service à un autre utilisateur Snowflake.

Limitations connues

L’interrogation d’un Cortex Search Service est soumise aux limitations suivantes :

  • Taille de la réponse : La taille totale de la charge utile de la réponse renvoyée par une requête de recherche à un Cortex Search Service ne doit pas dépasser les limites suivantes :