DOCUMENTATION
/
시작하기
가이드
개발자
참조
릴리스
자습서
Snowflake Open Catalog
상태

자습서 1: Cortex Search를 사용하여 간단한 검색 애플리케이션 개발

가이드Snowflake AI & MLCortex Search자습서자습서 1: 간단한 검색 애플리케이션 개발

자습서 1: Cortex Search를 사용하여 간단한 검색 애플리케이션 개발¶

소개¶

이 자습서에서는 간단한 검색 애플리케이션을 위한 Cortex Search를 시작하는 방법을 설명합니다.

알아볼 내용¶

  • AirBnb 목록 데이터 세트에서 Cortex Search Service를 생성합니다.

  • Cortex Search Service를 쿼리할 수 있는 Streamlit in Snowflake 앱을 생성합니다.

전제 조건¶

이 자습서를 완료하려면 다음과 같은 필수 조건이 필요합니다.

  • 데이터베이스, 테이블, 가상 웨어하우스 오브젝트, Cortex Search Service 및 Streamlit 앱을 만드는 데 필요한 권한을 부여하는 역할이 있는 Snowflake 계정과 사용자가 있습니다.

이러한 요구 사항을 충족하기 위한 지침은 20분만에 Snowflake 시작하기 섹션을 참조하십시오.

1단계: 설정¶

샘플 데이터 가져오기¶

Huggingface에서 호스팅 되는 샘플 데이터 세트를 사용하며, 단일 JSON 파일로 다운로드할 수 있습니다. 다음 링크를 따라 브라우저에서 직접 파일을 다운로드합니다.

  • AirBnB 목록 데이터 세트

참고

자습서 환경이 아닌 환경에서는 Snowflake 테이블에 이미 있는 데이터를 가져와서 사용할 수도 있습니다.

데이터베이스, 테이블, 웨어하우스 만들기¶

다음 문을 실행하여 이 자습서에 필요한 데이터베이스와 가상 웨어하우스를 생성합니다. 자습서를 마친 후 이러한 오브젝트를 삭제할 수 있습니다.

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;
Copy

다음 사항을 참고하십시오.

  • CREATE DATABASE 문으로 데이터베이스를 만듭니다. 데이터베이스에는 ‘public’이라는 스키마가 자동으로 포함됩니다.

  • CREATE WAREHOUSE 문으로 처음에 일시 중단되는 웨어하우스를 만듭니다. 또한 이 문으로 AUTO_RESUME = true 가 설정되어, 컴퓨팅 리소스가 필요한 SQL 문을 실행할 때 웨어하우스를 자동으로 시작하게 됩니다.

2단계: Snowflake에 데이터 로드¶

검색 서비스를 생성하려면 먼저 예제 데이터를 Snowflake에 로드해야 합니다.

데이터 세트는 Snowsight 에서 업로드하거나 SQL을 사용하여 업로드할 수 있습니다. Snowsight 에서 업로드하려면:

  1. 왼쪽 탐색 표시줄 위에 있는 + Create 버튼을 선택합니다.

  2. 그런 다음 Table » From File 을 선택합니다.

    Snowsight UI에 데이터 추가하기
  3. 오른쪽 상단 모서리에 있는 드롭다운에서 테이블의 웨어하우스로 새로 생성한 웨어하우스를 선택합니다.

  4. JSON 데이터 파일을 대화 상자에 끌어서 놓습니다.

  5. 위에서 생성한 데이터베이스를 선택하고 PUBLIC 스키마를 지정합니다.

  6. 마지막으로 이름이 airbnb_listings 인 새 테이블 생성을 지정하고 Next 를 선택합니다.

    Snowsight UI에 데이터 추가하기
  7. Load Data into Table 대화 상자에서 다음과 같이 조정합니다. 먼저 이 자습서에는 적용되지 않으므로 image_embeddings, images, text_embeddings 열의 선택을 취소합니다. 두 번째로, amenities 필드의 데이터 타입을 ARRAY 유형으로 조정합니다.

    Snowsight UI에 데이터 추가하기
    Snowsight UI에 데이터 추가하기
  8. 이러한 조정이 완료되면 Load 를 선택하여 계속 진행합니다.

  9. 잠시 후, 데이터가 로드되었다는 확인 페이지가 표시됩니다.

    Snowsight UI에 데이터 추가하기
  10. Query Data 를 선택하면 다음 단계에서 사용할 새 Snowsight 워크시트가 열립니다.

3단계: 검색 서비스 만들기¶

다음 SQL 명령을 실행하여 새 테이블에 대한 검색 서비스를 생성합니다.

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;
Copy
이 명령의 인자를 분석해 보겠습니다.
  • ON 매개 변수는 검색할 쿼리의 열을 지정합니다. 이 경우, 소스 쿼리에서 기본 테이블에 있는 여러 텍스트 열의 연결로 생성되는 listing_text 입니다.

  • ATTRIBUTES 매개 변수는 검색 결과를 필터링할 수 있는 열을 지정합니다. 이 예제는 listing_text 열에 쿼리를 발행할 때 room_type 및 amenities 에 필터링합니다.

  • WAREHOUSE 및 TARGET_LAG 매개 변수는 각각 사용자가 제공한 웨어하우스와 검색 서비스의 원하는 최신성을 지정합니다. 이 예제에서는 cortex_search_tutorial_wh 웨어하우스를 사용하여 인덱스를 생성하고 새로 고침을 수행하며, 소스 테이블 AIRBNB_LISTINGS 뒤에 서비스를 '1 hour' 이하로 유지하도록 지정합니다.

  • AS 필드는 서비스의 소스 테이블을 정의합니다. 이 예제에서는 원래 테이블의 여러 텍스트 열을 검색 열 listing_text 로 연결하여 쿼리가 여러 필드를 검색할 수 있도록 합니다.

단계 4: Streamlit 앱 생성¶

Python SDK로 서비스를 쿼리(snowflake Python 패키지 사용)할 수 있습니다. 이 자습서에서는 Streamlit in Snowflake 애플리케이션에서 Python SDK를 사용하는 방법을 보여줍니다.

먼저 서비스 생성 단계에서 전역 Snowsight UI 역할이 서비스를 생성하는 데 사용된 역할과 동일한지 확인합니다.

  1. Snowsight 에 로그인합니다.

  2. 왼쪽 탐색 메뉴에서 Projects » Streamlit 를 선택합니다.

  3. + Streamlit App 를 선택합니다.

  4. 중요: 앱 위치에 대한 cortex_search_tutorial_db 데이터베이스와 public 스키마를 선택합니다.

  5. Streamlit in Snowflake 편집기의 왼쪽 창에서 Packages 를 선택하고 snowflake (버전 >= 0.8.0)를 추가하여 애플리케이션에 패키지를 설치합니다.

  6. 예제 애플리케이션 코드를 다음 Streamlit 앱으로 바꿉니다.

    # 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()
    
    Copy

위의 Streamlit-in-Snowflake 코드의 주요 구성 요소에 대한 간략한 분석은 다음과 같습니다.

  • get_column_specification 은 DESCRIBE SQL 쿼리를 사용하여 검색 서비스에서 사용 가능한 특성에 대한 정보를 가져와 Stremalit 상태에 저장합니다.

  • init_layout 은 페이지의 헤더와 소개를 설정합니다.

  • query_cortex_search_service 는 Python 클라이언트 라이브러리를 통해 Cortex Search Service 쿼리를 처리합니다.

  • create_filter_object 는 Streamlit 양식에서 선택한 필터 특성을 적절한 오브젝트로 처리하여 Python 라이브러리가 Cortex Search를 쿼리하는 데 사용할 수 있도록 합니다.

  • distinct_values_for_attribute 는 필터링 가능한 각 특성에 대해 드롭다운 메뉴를 채울 수 있는 값을 결정합니다.

  • init_search_input, init_limit_input, init_attribute_selection 는 검색 쿼리에 대한 입력, 결과 수 제한, 특성 필터를 초기화합니다.

  • display_search_results 는 검색 결과를 결과 페이지에 표시되는 마크다운 요소로 서식을 지정합니다.

5단계. 정리¶

정리(선택 사항)¶

자습서를 시작하기 전의 상태로 시스템을 되돌리려면 다음 DROP <오브젝트> 명령을 실행합니다.

DROP DATABASE IF EXISTS cortex_search_tutorial_db;
DROP WAREHOUSE IF EXISTS cortex_search_tutorial_wh;
Copy

데이터베이스를 삭제하면 테이블과 같은 모든 하위 데이터베이스 오브젝트가 자동으로 제거됩니다.

다음 단계¶

축하합니다! Snowflake에서 텍스트 데이터를 기반으로 간단한 검색 앱을 성공적으로 생성했습니다. 자습서 2 로 이동하여 Cortex LLM 함수 에 레이어를 지정하여 Cortex Search로 AI 챗봇을 구축하는 방법을 살펴볼 수 있습니다.

추가 리소스¶

또한 다음 리소스를 사용하여 계속 학습할 수 있습니다.

  • Cortex Search 개요

  • Cortex Search Service 쿼리하기

이 페이지가 도움이 되었습니까?

Snowflake 방문하기
대화에 참여하기
Snowflake로 개발하기
피드백 공유하기
블로그에서 최신 게시물 읽기
자체 인증 받기
개인정보 보호정책사이트 이용약관© 2025 Snowflake, Inc. All Rights Reserved.
언어: 한국어
  • English
  • Français
  • Deutsch
  • 日本語
  • 한국어
  • Português