본문 바로가기
WIKI 기술 지식 베이스

UBI index schemas

원문 보기 위키 갱신

출처: 문서

본문

UBI 인덱스 스키마

User Behavior Insights(UBI) 데이터 수집 과정은 사용자가 제출한 쿼리를 추적하고 기록하는 것과 더불어, 검색 결과를 받은 후의 후속 행동이나 이벤트를 모니터링하고 로깅하는 것도 포함해요. 데이터 수집 과정에는 두 가지 UBI 인덱스 스키마가 관여해요:

핵심 식별자

UBI가 제대로 작동하려면, UBI가 활성화된 애플리케이션 내에서 다음 필드들 간의 연결이 일관되게 유지되어야 해요:

  • object_id는 쿼리에 대한 응답으로 사용자가 받는 객체의 ID를 나타내요. 예를 들어, 책을 검색한다면 978-3-16-148410-0 같은 책의 ISBN일 수 있죠.
  • query_id는 실행된 원시 쿼리의 고유 ID예요. 반면 object_id는 사용자의 쿼리가 반환한 _hits_의 기본 식별자에 매핑돼요.
  • client_id는 고유한 쿼리 소스를 나타내요. 보통 특정 사용자가 사용하는 웹 브라우저를 말하죠.
  • object_id_field는 object_id를 제공하는 인덱스 내 필드의 이름을 지정해요. 예를 들어, 책을 검색한다면 값이 isbn_code일 수 있죠.
  • action_name은 엄밀히 말하면 ID는 아니지만, 주어진 object_id를 가진 객체에 대해 수행되었(거나 수행되지 않았)은 정확한 사용자 행동(예: click, add_to_cart, watch, view, purchase)을 지정해요.

요약하면, query_id는 client_id를 통해 추적되는 클라이언트의 고유한 검색이 시작됐음을 알려줘요. 검색은 각각 고유한 object_id를 가진 다양한 객체들을 반환하죠. action_name은 사용자가 수행 중인 행동을 지정하며, 각각 특정 object_id를 가진 객체들과 연결돼요. object_id_field를 살펴보면 객체 유형을 구분할 수 있어요.

일반적으로 사용자의 client_id에 대한 모든 데이터를 가져오고 개별 query_id 데이터를 살펴봄으로써 사용자의 전체 검색 기록을 추론할 수 있어요. 각 애플리케이션은 백엔드 데이터를 살펴봄으로써 무엇이 검색 세션을 구성하는지 결정해요.

중요한 UBI 역할

다음 다이어그램은 사용자가 검색 클라이언트와 UBI 클라이언트와 상호작용하는 과정과, 이들이 다시 UBI events 및 UBI queries 인덱스를 담고 있는 OpenSearch 클러스터와 상호작용하는 방식을 보여줘요.

파란색 화살표는 표준 검색을 나타내고, 굵은 점선은 UBI 고유의 추가 요소를 나타내며, 빨간색 화살표는 query_id가 OpenSearch로 오가는 흐름을 나타내요.

{% comment %} 아래의 mermaid 소스는 .../images/ubi/ubi-schema-interactions.png 경로 아래에서 PNG로 변환돼요

graph LR
style L fill:none,stroke-dasharray: 5 5
subgraph L["`*Legend*`"]
  style ss height:150px
  subgraph ss["Standard Search"]
   direction LR
    
   style ln1a fill:blue
   ln1a[ ]--->ln1b[ ];
  end
  subgraph ubi-leg["UBI data flow"]
   direction LR
   
   ln2a[ ].->|"`**UBI interaction**`"|ln2b[ ];
   style ln1c fill:red
   ln1c[ ]-->|<span style="font-family:Courier New">query_id</span> flow|ln1d[ ];
  end
end
linkStyle 0 stroke-width:2px,stroke:#0A1CCF
linkStyle 2 stroke-width:2px,stroke:red
%%{init: {
  "flowchart": {"htmlLabels": false},

  } 
}%%
graph TB

User--1) <i>raw search string</i>-->Search;  
Search--2) <i>search string</i>-->Docs 
style OS stroke-width:2px, stroke:#0A1CCF, fill:#62affb, opacity:.5
subgraph OS[OpenSearch Cluster fa:fa-database]
  style E stroke-width:1px,stroke:red
  E[(&emsp;<b>UBI Events</b>&emsp;)]
  style Docs stroke-width:1px,stroke:#0A1CCF
  style Q stroke-width:1px,stroke:red
  Docs[(Document Index)] -."3) {<i>DSL</i>...} & [<i>object_id's</i>,...]".-> Q[(&emsp;<b>UBI Queries</b>&emsp;)]; 
  Q -.4) <span style="font-family:Courier New">query_id</span>.-> Docs ;  
end

Docs -- "5) <i>return</i> both <span style="font-family:Courier New">query_id</span> & [<i>objects</i>,...]" --->Search ;
Search-.6) <span style="font-family:Courier New">query_id</span>.->U;
Search --7) [<i>results</i>, ...]--> User

style *client-side* stroke-width:1px, stroke:#D35400
subgraph "`*client-side*`"
  style User stroke-width:4px, stroke:#EC636
  User["`**User**`" fa:fa-user]
  App
  Search  
  U
  style App fill:#D35400,opacity:.35, stroke:#0A1CCF, stroke-width:2px
  subgraph App[&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;UserApp fa:fa-store]
    style Search stroke-width:2px, stroke:#0A1CCF
    Search(&emsp;Search Client&emsp;)    
    style U stroke-width:1px,stroke:red
    U(&emsp;<b>UBI Client</b>&emsp;)
  end
end

User -.8) <i>selects</i> <span style="font-family:Courier New">object_id:123</span>.->U;
U-."9) <i>index</i> event:{<span style="font-family:Courier New">query_id, onClick, object_id:123</span>}".->E;

linkStyle 1,2,0,6 stroke-width:2px,fill:none,stroke:#0A1CCF
linkStyle 3,4,5,8 stroke-width:2px,fill:none,stroke:red

{% endcomment %} 역할에 관한 주요 사항은 다음과 같아요:

  • 검색 클라이언트는 검색을 수행한 뒤 OpenSearch 문서 인덱스로부터 객체를 받는 역할을 담당해요(앞선 다이어그램의 1, 2, 5, 7).

5 단계가 굵게 표시된 이유는, 표준 OpenSearch 상호작용에 더해지는 query_id 같은 UBI 고유의 추가 요소를 나타내기 때문이에요. {: .note}

  • 검색 요청의 ext.ubi 스탠자에서 활성화되면, User Behavior Insights 플러그인이 백그라운드에서 UBI queries 스토어를 관리하면서 각 쿼리를 인덱싱하고, 반환되는 모든 object_id 값에 대해 고유한 query_id를 보장한 뒤, 이벤트가 쿼리에 연결될 수 있도록 query_id를 검색 클라이언트에 다시 전달해요(앞선 다이어그램의 3, 4, 5).
  • 객체는 사용자가 쿼리를 사용해 검색하는 항목을 나타내요. UBI를 활성화하려면 실세계의 객체(isbn이나 sku 같은 식별자를 사용)를 검색 대상 인덱스의 object_id 필드에 매핑하는 작업이 필요해요.
  • 검색 클라이언트는 UBI 클라이언트와 별도로 분리되어 있는 경우, 인덱싱된 query_id를 UBI 클라이언트에 전달해요. 이 다이어그램에서 검색과 UBI 이벤트 인덱싱 역할이 분리되어 있긴 하지만, 많은 구현에서는 두 역할 모두에 동일한 OpenSearch 클라이언트 인스턴스를 사용할 수 있어요(앞선 다이어그램의 6).
  • 그러면 UBI 클라이언트는 새 검색이 수행될 때까지 지정된 query_id로 모든 사용자 이벤트를 인덱싱해요. 이 시점에 User Behavior Insights 플러그인이 새로운 query_id를 생성하여 UBI 클라이언트에 다시 전달해요.
  • UBI 클라이언트가 장바구니 추가 이벤트처럼 결과 객체와 상호작용하면, object_id, add_to_cart action_name, query_id가 모두 함께 인덱싱되어 검색과 객체 사이의 인과 관계를 나타내요(앞선 다이어그램의 8과 9).

UBI 스토어

UBI 데이터 수집을 지원하는 데에는 두 개의 별도 스토어가 관여해요:

  • UBI queries
  • UBI events

UBI queries 인덱스

모든 기저 쿼리 정보와 결과(object_ids)는 ubi_queries 인덱스에 저장되며, 대체로 백그라운드에서 보이지 않는 상태로 유지돼요.

ubi_queries 인덱스 스키마에는 다음 필드들이 포함되어 있어요:

  • timestamp (이벤트와 쿼리): 쿼리가 수신된 시점을 나타내는 ISO 8601 형식의 타임스탬프예요.

  • query_id (이벤트와 쿼리): 클라이언트가 제공하거나 검색 엔진이 생성한 쿼리의 고유 ID예요. 동일한 텍스트를 가진 서로 다른 쿼리는 서로 다른 query_id 값을 생성해요.

  • client_id (이벤트와 쿼리): 클라이언트 애플리케이션이 제공하는 클라이언트 ID예요.

  • query_response_objects_ids (쿼리): 객체 ID의 배열이에요. ID는 _id와 같은 값을 가질 수도 있지만, 이는 문서, 항목, 제품의 외부적으로 유효한 ID를 의미해요.

UBI가 ubi_queries 인덱스를 관리하기 때문에, (데이터를 가져오는 경우를 제외하면) 이 인덱스에 직접 쓸 일은 전혀 없어야 해요.

UBI events 인덱스

클라이언트 측은 이벤트를 ubi_events 인덱스에 직접 인덱싱하며, 이때 이벤트의 action_name과 객체(각각 object_id를 가짐), 쿼리(각각 query_id를 가짐)를 그 밖의 중요한 이벤트 정보와 함께 연결해요. 이 스키마는 동적이므로, 인덱싱 시점에 현재 UBI events 스키마에 없는 새로운 필드나 구조(예: 사용자 정보나 지리적 위치 정보)를 추가할 수 있어요.

개발자는 event_attributes 아래에 새로운 필드를 정의할 수 있어요. {: .note}

다음은 ubi_events 인덱스에 사전 정의된 최소한의 필드들이에요:

  • application (size 100): UBI 이벤트를 추적하는 애플리케이션의 이름이에요(예: amazon-shop 또는 ABC-microservice).

  • action_name (size 100): 이벤트를 트리거한 액션의 이름이에요. UBI 사양에서 몇 가지 일반적인 액션 이름을 정의하고 있지만, 어떤 이름이든 사용할 수 있어요.

  • query_id (size 100): 쿼리의 고유 식별자로, 일반적으로 UUID지만 어떤 문자열이든 될 수 있어요. query_id는 클라이언트가 제공하거나 쿼리 시점에 UBI 플러그인이 생성해요. UBI queries 인덱스와 UBI events 인덱스 양쪽에서 query_id 값은 일관되게 유지되어야 해요.

  • client_id: 쿼리를 발행하는 클라이언트예요. 보통 특정 사용자가 사용하는 웹 브라우저죠. UBI queries 인덱스와 UBI events 인덱스 양쪽에서 client_id는 일관되게 유지되어야 해요.

  • timestamp: 이벤트가 발생한 시간으로, 2018-11-13T20:20:39+00:00Z 같은 ISO 8601 형식이에요.

  • message_type (size 100): 액션(각각 action_name을 가짐)을 그룹화하기 위한 논리적인 분류 단위예요. 예를 들어 QUERY 또는 CONVERSION이 있죠.

  • message (size 1,024): 로그 항목을 위한 선택적 텍스트 메시지예요. 예를 들어 message_type이 QUERY인 경우, message에는 사용자의 검색과 관련된 텍스트가 담길 수 있어요.

  • event_attributes: 이벤트에 대한 중요한 맥락을 설명하는 확장 가능한 구조예요. 이 구조는 position과 object라는 두 가지 기본 구조로 구성돼요. 확장 가능한 구조이므로, 이벤트의 시점, 사용자, 세션 같은 이벤트 관련 사용자 지정 정보를 추가할 수 있어요.

ubi_events 인덱스는 동적 매핑을 수행하도록 구성되어 있기 때문에, 수많은 새 필드로 인덱스가 비대해질 수 있어요. {: .warning}

  • event_attributes.position: 화면 x, y 좌표나 결과 목록에서의 객체 위치 같은, 이벤트 발생 위치에 대한 정보를 담고 있는 구조예요:

    • event_attributes.position.ordinal: 사용자가 선택할 수 있는 목록 상의 위치를 추적해요(예를 들어, 세 번째 요소를 선택하는 것은 event{onClick, results[4]}로 표현할 수 있어요).

    • event_attributes.position.xy.{x,y}: 클라이언트가 정의한 x와 y 값을 추적해요.

  • event_attributes.object: 쿼리가 반환한 객체(예: 책, 제품, 게시물)에 대한 식별 정보를 담고 있어요. object 구조는 내부 ID나 객체 ID로 객체를 참조할 수 있어요. object_id는 이전 쿼리들을 이 객체와 연결하는 ID예요. 이 필드는 다음과 같은 하위 필드들로 구성돼요:

    • event_attributes.object.internal_id: OpenSearch가 객체를 내부적으로 인덱싱할 때 사용하는 고유 ID예요. 예를 들어 인덱스의 _id 필드가 있죠.

    • event_attributes.object.object_id: 사용자가 문서 코퍼스에서 객체 인스턴스를 찾을 때 사용하는 ID예요. 예로는 ssn, isbn, ean이 있죠. 변형(variant)은 object_id에 반영되어야 하므로, 빨간색 티셔츠의 object_id는 해당 SKU가 되어야 해요. UBI를 초기화하려면 문서 인덱스의 기본 키를 이 object_id에 매핑해야 해요.

    • event_attributes.object.object_id_field: 객체의 유형/클래스와 object_id를 담고 있는 검색 인덱스 필드의 이름을 나타내요. 예로는 ssn, isbn, ean이 있죠.

    • event_attributes.object.description: 객체에 대한 선택적 설명이에요.

    • event_attributes.object.object_detail: 객체에 대한 선택적 추가 정보예요.

    • 확장 가능 필드: object에 새로 인덱싱되는 필드가 생기면 이 스키마가 동적으로 확장된다는 점에 유의해야 해요.

더 알아보기 (Learn more)