오브젝트셋은 단일 유형의 오브젝트들의 순서 없는 컬렉션을 나타냅니다. Functions API를 사용하여 오브젝트셋을 필터링하고, 정의된 링크 유형을 기반으로 다른 오브젝트 유형으로 Search Around을 수행하며, 집계된 값이나 구체적인 오브젝트를 검색할 수 있습니다. Function에 개별 오브젝트를 입력으로 전달하는 것 외에도 오브젝트 검색 API를 사용하여 언제든지 오브젝트셋을 검색할 수 있습니다.
필터링, 정렬, 집계는 온톨로지 앱에서 Searchable
렌더 힌트가 활성화된 속성에서만 작동합니다. 이러한 속성은 검색용으로 색인화되어 있습니다. Searchable
렌더 힌트를 활성화하는 방법 알아보기.
Objects.search()
인터페이스를 사용하면 프로젝트에 가져온 오브젝트 유형 중 하나를 검색할 수 있습니다. 이 예에서 Function은 주어진 airportCode
를 사용하여 해당 공항에서 출발한 모든 항공편을 찾습니다. 그런 다음 그 항공편의 모든 고유한 목적지를 찾아 반환합니다.
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
import { Function } from "@foundry/functions-api"; import { Objects } from "@foundry/ontology-api"; export class FlightFunctions { @Function() // 현재 비행 목적지 함수 (공항 코드를 인자로 받음) public currentFlightDestinations(airportCode: string): Set<string> { // 주어진 공항에서 출발하는 모든 비행기를 검색 const flightsFromAirport = Objects.search() .flights() .filter(flight => flight.departureAirportCode.exactMatch(airportCode)) .all(); // 각 비행기의 도착 공항 코드를 배열로 만듬 const destinations = flightsFromAirport.map(flight => flight.arrivalAirportCode!); // 중복을 제거하기 위해 Set으로 변환 return new Set(destinations); } }
오브젝트셋은 오브젝트 목록, 오브젝트 리소스 식별자 목록 또는 오브젝트셋 리소스 식별자를 인수로 전달하여 생성할 수도 있습니다. 예를 들어, Objects.search().flights([flight])
.
특정 유형의 오브젝트셋을 갖게 되면 아래에 문서화된 대로 셋에서 다양한 작업을 수행할 수 있습니다.
오브젝트셋의 .filter()
메소드는 오브젝트의 검색 가능한 속성을 기준으로 오브젝트셋을 필터링할 수 있습니다. 필터 메소드는 필터 정의를 사용하며, 이는 필터링하는 속성의 유형에 따라 다릅니다.
모든 속성 유형은 .exactMatch()
필터를 지원하며, 해당 속성 값이 정확히 일치하는 오브젝트를 필터링합니다. 이는 문자열에서 정확한 일치 항목을 필터링하거나 오브젝트의 기본 키를 기준으로 필터링하는 데 유용합니다(예: .filter(object => object.primaryKey.exactMatch(PrimaryKey))
).
null
이거나 undefined
인지 확인하려면 hasProperty()
메소드를 사용하세요.문자열 속성은 여러 키워드 필터를 지원합니다. 각 메소드의 코드 어시스트에 대한 문서를 참조하세요.
.phrase()
는 주어진 구문을 포함하는 값에 따라 필터링합니다. 하이픈, 밑줄 또는 마침표로 구분된 연결된 단어가 있는 문자열 값은 하나의 구문으로 취급됩니다. 예를 들어, "banana"를 검색할 때 속성 값이 "banana_pudding"인 오브젝트는 반환되지 않습니다..phrasePrefix()
는 주어진 구문과 접두사로 시작하는 값에 따라 필터링합니다. 예를 들어, banana
에 대한 .phrasePrefix()
검색은 속성 값이 banana_pudding
인 오브젝트를 반환합니다. 그러나 pudding
에 대한 .phrasePrefix()
검색은 속성 값이 banana_pudding
과 일치하지 않습니다..prefixOnLastToken()
은 마지막 토큰을 접두사로 처리하여 주어진 구문을 포함하는 값에 따라 필터링합니다..matchAnyToken()
, .fuzzyMatchAnyToken()
은 검색 쿼리를 토큰(보통 개별 단어)으로 분리한 다음 주어진 토큰 중 하나를 포함하는 값에 따라 필터링합니다. fuzzy
버전은 대략적인 값에 일치할 수 있습니다. 검색 쿼리 또는 속성 값에 하이픈, 밑줄, 마침표가 포함된 경우, 연결된 단어일지라도 하나의 토큰 또는 구문으로 처리됩니다..matchAllTokens()
, .fuzzyMatchAllTokens()
은 검색 쿼리를 토큰(보통 개별 단어)으로 분리한 다음 주어진 토큰을 모두 포함하는 값에 따라 필터링합니다. fuzzy
버전은 대략적인 값에 일치할 수 있습니다.
@foundry/functions-api
에서 가져온 선택적 Fuzziness
파라미터를 사용할 수 있습니다.Fuzziness
옵션에 대한 설명은 ElasticSearch 문서에서 찾을 수 있습니다. 아래에 더 많은 정보도 있습니다.숫자, 날짜 및 타임스탬프 속성은 .range()
필터를 지원합니다.
.lt()
, .lte()
, .gt()
및 gte()
메소드 세트가 있습니다.부울 속성은 .isTrue()
및 .isFalse()
필터를 지원합니다.
Geohash 속성은 .withinDistanceOf()
, .withinPolygon()
, 및 .withinBoundingBox()
필터를 지원합니다.
GeoShape 속성은 .withinBoundingBox()
, .intersectsBoundingBox()
, .doesNotIntersectBoundingBox()
, .withinPolygon()
, .intersectsPolygon()
, 및 doesNotIntersectPolygon()
필터를 지원합니다.
링크 필터는 .isPresent()
메소드를 사용하여 특정 유형의 연결된 오브젝트가 있는 또는 없는 오브젝트를 필터링하는 데 사용할 수 있습니다.
배열 속성은 .contains()
필터를 지원하며, 주어진 값 중 어떤 값을 포함하는 배열 속성 값의 오브젝트로 필터링합니다.
@foundry/functions-api
에서 내보낸 Filters
API를 사용하여 필터를 함께 구성할 수 있습니다. 사용 가능한 메소드는 다음과 같습니다:
and()
는 주어진 모든 필터를 통과하는 오브젝트셋을 필터링합니다.or()
는 주어진 필터 중 하나를 통과하는 오브젝트셋을 필터링합니다.not()
은 주어진 필터를 부정합니다.아래 예제에서는 and()
를 사용하여 항공편 오브젝트셋을 항공편 목적지별로 필터링할 수 있습니다:
Copied!1 2 3 4 5 6 7 8 9 10 11
import { Filters } from "@foundry/functions-api"; Objects.search() .flights() .filter(flight => Filters.or( // 비행기의 목적지가 "SFO"이고 승객 수가 100명 초과인 경우 Filters.and(flight.destination.exactMatch("SFO"), flight.passengerCount.gt(100)), // 비행기의 목적지가 "LAX"이고 승객 수가 300명 초과인 경우 Filters.and(flight.destination.exactMatch("LAX"), flight.passengerCount.gt(300)), ))
위의 코드는 SFO에 100명 이상의 승객이 도착한 비행기나 LAX에 300명 이상의 승객이 도착한 비행기를 필터링합니다.
오브젝트셋에서 .filter()
메소드는 &&
또는 ||
연산자를 사용하지 않습니다. 여러 필터를 적용하려면 위에 나열된 Filters
의 메소드 중 하나를 사용해야 합니다(또는 and
조건을 달성하기 위해 .filter()
를 여러 번 호출해야 합니다).
선택적인 fuzziness
파라미터를 지정하면 퍼지 일치 동작을 더 세밀하게 제어할 수 있습니다. fuzziness
를 지정하지 않으면 검색하는 토큰의 길이에 따라 자동 수정 거리가 허용됩니다. 수정 거리를 지정하려면 @foundry/functions-api
에서 Fuzziness
를 가져와야 합니다.
// 아래 코드는 퍼지 검색을 사용해 "Michael"이라는 이름을 가진 직원을 검색하는 것입니다.
// "fuzziness" 옵션으로 LEVENSHTEIN_TWO를 사용하면, 레벤슈타인 거리가 2 이하인 모든 결과를 반환합니다.
// 즉, "Michael"이라는 이름에서 최대 두 문자가 변경된 모든 직원을 찾습니다.
Objects.search().employee().filter(employee => employee.firstName.fuzzyMatchAnyToken("Michael", { fuzziness: Fuzziness.LEVENSHTEIN_TWO })).all();
위의 코드는 제공된 검색어와 레벤슈타인 거리가 두 개의 수정 내에 있는 모든 직원의 첫 이름을 반환합니다. 이 예에서는 Michael
, Micheal
, Mikhael
, Michel
, Mikhail
, Mihail
이 포함되지만 Miguel
은 포함되지 않습니다. 검색어의 정확성에 대해 더 확신이 있으면 더 작은 수정 거리(다른 레벤슈타인 거리로)로 검색하여 검색 결과를 좀 더 세밀하게 조정할 수 있습니다.
// 객체에서 직원을 검색하고, 퍼지 매칭을 사용하여 "Michael Smith"와 가장 가까운 이름을 가진 직원을 찾습니다.
// 이때, 레벤슈타인 거리 1만큼의 오차를 허용합니다.
Objects.search().employee().filter(employee => employee.fullName.fuzzyMatchAllTokens("Michael Smith", { fuzziness: Fuzziness.LEVENSHTEIN_ONE })).all();
또한 여러 토큰 구문에 대해 퍼지 필터를 사용할 수 있습니다. 위의 코드는 Michael
과 Smith
를 모두 포함하는 전체 이름의 직원과 일치하며, 각 토큰에 최대 한 번의 편집이 허용됩니다(예: Mikhael Smitt
- 레벤슈타인 거리가 각각 1인 경우). fuzzyMatchAllTokens
또는 fuzzyMatchesAllTokens
필터에서 토큰의 순서는 고려되지 않습니다.
배열 기반 속성에 대한 모든 필터는 해당 기본 유형에 사용 가능한 메서드를 사용할 수 있습니다. 예를 들어, 문자열 배열 속성은 문자열 속성에 사용 가능한 모든 메서드를 기반으로 필터링 될 수 있으며, 메서드의 이름이 약간 다를 수 있습니다. 배열 속성에 대한 필터링은 배열 요소 중 하나와 일치해야 해당 오브젝트가 반환됩니다.
메모리에 로드된 오브젝트셋 .all()
또는 .allAsync()
는 최대 3개의 주변 검색이 허용됩니다. 3개 이상의 주변 검색이 사용되면 오류가 발생합니다.
오브젝트셋의 오브젝트 유형에 따라, 주변 검색 메서드가 생성되어 오브젝트셋의 오브젝트 유형에 따른 링크를 탐색할 수 있게 합니다. 아래 예시에서는 출발 코드를 기반으로 한 항공편의 오브젝트셋을 필터링한 다음, 해당 항공편의 승객으로 주변 검색을 수행합니다. 이렇게 하면 승객의 오브젝트셋이 생성되어 추가로 필터링되거나 주변 검색이 수행됩니다.
Copied!1 2 3 4 5 6
// 아래 코드는 특정 공항에서 출발하는 승객들을 찾는데 사용됩니다. const passengersDepartingFromAirport = Objects.search() // Objects에서 search 메서드를 호출하여 검색을 시작합니다. .flights() // flights 메서드를 호출하여 모든 비행 정보를 가져옵니다. .filter(flight => flight.departureAirportCode.exactMatch(airportCode)) // filter 메서드를 사용하여 출발 공항 코드가 airportCode와 정확히 일치하는 비행편만 선택합니다. .searchAroundPassengers(); // searchAroundPassengers 메서드를 호출하여 해당 비행편의 승객들을 검색합니다.
Search Around 방법은 프로젝트에 가져온 링크 유형에 대해서만 생성됩니다. 링크 유형을 가져오는 방법에 대한 자세한 내용은 튜토리얼을 참조하십시오.
성능상의 이유로 한 번의 검색에서 수행할 수 있는 Search Around 작업의 수는 현재 3개로 제한되어 있습니다. Search Around 깊이가 세 단계 이상인 검색을 시도하면 런타임에서 검색이 실패합니다.
KNN은 OSv2로 색인화된 오브젝트 유형에서만 지원됩니다. k 값의 범위는 0 < K <= 100으로 제한됩니다. 또한, 검색 벡터는 색인화에 사용된 것과 크기가 같아야 하며, 차원은 2048로 제한됩니다. 이러한 제한을 초과하면 오류가 발생합니다.
임베딩 속성이 있는 오브젝트 유형은 KNN 검색에 사용할 수 있습니다. 이러한 검색은 제공된 임베딩 파라미터에 가장 가까운 임베딩 속성을 가진 k 값 오브젝트를 반환합니다. 다음 예는 제공된 영화 대본과 가장 유사한 영화를 반환합니다. 쿼리 시간에 임베딩을 생성하려면 모델링 라이브 배포 설정이 필요합니다.
functions.json
에 enableVectorProperties
가 true
로 설정되어 있는지 확인하십시오.
Copied!1 2 3 4 5 6 7 8 9 10 11
import { Objects } from "@foundry/ontology-api"; const kValue: number = 2; // 벡터는 FML Live에서 생성되거나 기존 객체에서 가져올 수 있습니다. const vector: Double[] = [0.7, 0.1, 0.3]; // 영화를 검색하여 가장 가까운 이웃을 찾고, 관련성순으로 정렬합니다. const movies: Movies[] = Objects.search() .movies() .nearestNeighbors(obj => obj.vectorProperty.near(vector, { kValue })) // 벡터와 가장 가까운 이웃을 찾습니다. .orderByRelevance() // 관련성순으로 정렬합니다. .take(kValue); // kValue 개수만큼 결과를 가져옵니다.
예를 들어 전체 시맨틱 검색 워크플로를 보려면 시맨틱 검색 워크플로 가이드를 참조하세요.
같은 오브젝트 유형의 오브젝트셋은 다음과 같은 집합 연산을 사용하여 여러 가지 방식으로 결합할 수 있습니다.
.union()
은 주어진 오브젝트셋에 있는 오브젝트로 구성된 새로운 오브젝트셋을 생성합니다..intersect()
는 주어진 오브젝트셋의 모든 오브젝트로 구성된 새로운 오브젝트셋을 생성합니다..subtract()
는 주어진 오브젝트셋에 있는 오브젝트를 제거합니다..all()
및 .allAsync()
메소드는 오브젝트셋의 모든 오브젝트를 검색합니다. 한 번에 너무 많은 오브젝트를 로드하려고 하면 Function이 실행되지 않습니다. 현재 로드할 수 있는 최대 오브젝트 수는 100,000개입니다. 하지만 10,000개 이상의 오브젝트를 로드하면 Function 실행이 시간 초과될 수도 있습니다. Functions에서의 시간 및 공간 제한에 대해 더 알아보기.
.allAsync()
메소드를 사용하여 오브젝트셋의 모든 오브젝트를 확인하는 Promise를 검색할 수 있습니다. 이는 여러 오브젝트셋에서 데이터를 병렬로 로드하는 데 유용할 수 있습니다.
모든 오브젝트를 검색하는 대신 오브젝트셋에 정렬 절을 적용한 다음 로드할 오브젝트의 특정 수를 지정하여 제한된 수만큼 로드할 수 있습니다. 이렇게 하려면 다음 메소드를 사용할 수 있습니다.
.orderBy()
는 정렬 방향을 지정할 수 있게 하여 검색 가능한 속성을 정렬 기준으로 지정합니다. 정렬 가능한 유형(숫자, 날짜, 문자열)만이 이 메소드에서 선택 가능한 속성입니다. 여러 속성을 기준으로 정렬하려면 .orderBy()
를 여러 번 호출할 수 있습니다..orderByRelevance()
는 제공된 필터와 얼마나 잘 일치하는지에 따라 오브젝트를 반환하도록 지정하며, 가장 관련성이 높은 것부터 나열됩니다. 주어진 오브젝트의 속성 값에 대한 쿼리 용어와 관련성은 용어가 속성 값에 나타나는 빈도, 모든 오브젝트에서 나타나는 용어의 빈도 등을 고려한 복잡한 결정입니다. .exactMatch()
필터만 수행하거나 문자열이 아닌 속성에 대한 필터링을 수행할 때 관련성이 덜 적합합니다. 하나의 검색에서 .orderBy()
와 .orderByRelevance()
중 하나만 사용할 수 있습니다..take()
및 .takeAsync()
는 집합에서 지정된 수의 오브젝트를 검색할 수 있게 합니다. 이러한 메소드는 정렬을 지정한 후에만 사용할 수 있습니다.예를 들어 다음 코드는 시작 날짜가 가장 이른 10명의 직원을 검색합니다.
Copied!1 2 3 4
Objects.search() // Objects에서 검색을 시작합니다. .employees() // 직원들에 대한 데이터를 가져옵니다. .orderBy(e => e.startDate.asc()) // 직원들의 시작 날짜를 오름차순으로 정렬합니다. .take(10) // 정렬된 결과 중 상위 10개의 항목만 가져옵니다.
다른 예로, 보험 회사의 사고 보험 청구 내용을 포함하는 오브젝트 유형 claims
이 있다고 상상해보세요. 빨간 차와 사슴이 관련된 특정한 청구를 찾고 싶습니다. .orderByRelevance()
줄이 없으면 빨간
, 자동차
, 충돌
, 사슴
과 같은 단어를 포함하는 결과물 중 상위 10개의 결과가 반환될 수 있습니다. 하지만 .orderByRelevance()
줄이 있으면 검색어를 가장 많이 포함하는 청구가 먼저 나오므로 가장 관련성이 높은 청구가 먼저 나타납니다.
Copied!1 2 3 4 5 6 7 8
const results = Objects.search() .claims() // "red car collision with deer"와 일치하는 토큰이 있는 문서를 필터링합니다. .filter(doc => doc.text.matchAnyToken("red car collision with deer")) // 관련성이 높은 순서대로 정렬합니다. .orderByRelevance() // 상위 10개 결과만 가져옵니다. .take(10)
Objects API에서 반환된 집계는 총 10,000개의 버킷으로 제한됩니다. 이 제한을 초과하면 오류가 발생합니다.
.topValues()
를 사용하여 버킷을 구분할 때, 데이터에 1,000개가 넘는 고유한 값이 있으면 결과는 근사치로 나타납니다. 이 경우 상위 값 목록이 정확하지 않을 수 있습니다.
많은 경우에 오브젝트셋의 모든 오브젝트를 로드할 필요가 없습니다. 대신 값의 버킷으로 집계된 집계를 로드하여 추가 분석을 수행할 수 있습니다.
집계를 계산하기 시작하려면 오브젝트셋에서 .groupBy()
메서드를 호출하십시오. 이를 통해 오브젝트셋의 오브젝트 유형에서 검색 가능한 속성 중 하나에 버킷 구분을 지정할 수 있습니다. 예를 들어, 이 코드는 시작 날짜별로 직원을 그룹화합니다:
Copied!1 2 3
Objects.search() .employees() // 직원 검색 .groupBy(e => e.startDate.byDays()) // 직원의 시작 날짜를 일 단위로 그룹화
속성 유형에 따라 버킷을 어떻게 만들어야 할지에 대한 추가 정보를 제공해야 할 때:
boolean
속성의 경우, 유일한 옵션은 .topValues()
입니다. 이는 true
와 false
에 대해 두 개의 버킷을 반환합니다..topValues()
: 빠른 응답 시간과 카디널리티가 작은 속성에 대해 이를 사용합니다. 이는 문자열 속성에 대한 상위 1,000개의 값을 기준으로 버킷을 만듭니다. 이 제한은 반환된 집계가 과도하게 크지 않도록 하기 위함입니다..exactValues()
: 더 정확한 집계 및 고 카디널리티 속성에 대해 10,000개 이상의 버킷을 고려할 수 있습니다. 고려된 버킷의 수량은 .exactValues({"maxBuckets": numBuckets})
를 통해 지정할 수 있으며, 여기서 numBuckets
는 0과 10,000 사이의 정수값이어야 합니다. 이 방법의 응답 시간은 더 많은 결과가 고려되어야 하므로 더 길어질 수 있습니다.Integer
, Long
, Float
, Double
)의 경우, 두 가지 버킷 옵션이 있습니다:
.byRanges()
는 사용해야 할 정확한 범위를 지정할 수 있습니다. 예를 들어, .byRanges({ min: 0, max: 50 }, { min: 50, max: 100 })
를 사용하여 오브젝트를 [0, 50] 및 [50, 100]의 두 범위로 버킷화할 수 있습니다. 범위의 min
은 포함되며 max
는 제외됩니다. min
또는 max
를 생략하여 -∞에서 max
또는 min
에서 ∞까지의 값을 포함하는 버킷을 나타낼 수 있습니다..byFixedWidth()
는 각 버킷의 너비를 지정합니다. 예를 들어, .byFixedWidth(50)
을 사용하여 각각 50의 너비를 가진 범위로 오브젝트를 버킷화할 수 있습니다.LocalDate
속성의 경우, 쉬운 버킷화를 위해 다양한 편리한 방법이 제공됩니다:
.byYear()
.byQuarter()
.byMonth()
.byWeek()
.byDays()
은 값을 일자로 버킷화합니다. 버킷 너비를 위해 일수를 입력할 수 있습니다.Timestamp
속성의 경우, LocalDate
에 적용되는 동일한 버킷 옵션이 적용되며, 다음 추가 항목들이 있습니다:
.byHours()
는 값을 시간으로 버킷화합니다. 버킷 너비를 위해 시간 수를 입력할 수 있습니다..byMinutes()
는 값을 분으로 버킷화합니다. 버킷 너비를 위해 분 수를 입력할 수 있습니다..bySeconds()
는 값을 초로 버킷화합니다. 버킷 너비를 위해 초 수를 입력할 수 있습니다.Array
속성의 경우, 버킷 옵션은 배열의 요소 유형에 따라 결정됩니다. 특히, Array<PropertyType>
에 대한 버킷화 방법은 PropertyType
에 대한 버킷화 방법과 동일합니다(예를 들어, Array<boolean>
은 boolean
에 대한 동일한 버킷화 방법을 얻습니다).
["US", "UK"]
와 ["US"]
에서 일한 Array<string>
인 employeeSet
이 있다고 가정하면, employeeSet.groupBy(e => e.pastCountries.exactValue()).count()
는 { "US": 2, "UK": 1 }
을 반환합니다.속성별로 그룹화한 후에는, .segmentBy()
메소드를 호출하여 추가 버킷화를 수행할 수 있습니다. 이를 통해 두 검색 가능 속성에 의해 버킷화된 3차원 집계를 계산할 수 있습니다. 예를 들어, 직원을 시작 날짜와 역할에 따라 그룹화할 수 있습니다:
Copied!1 2 3 4 5 6 7 8
// 객체 탐색 메소드를 실행합니다. Objects.search() // 직원들의 데이터를 가져옵니다. .employees() // 직원들의 데이터를 시작일(일 단위)에 따라 그룹화합니다. .groupBy(e => e.startDate.byDays()) // 그룹화된 데이터를 직원들의 역할에 따라 세분화합니다. .segmentBy(e => e.role.topValues())
오브젝트셋을 그룹화한 후, 각 버킷에서 집계 측정치를 계산하기 위해 다양한 집계 방법을 호출할 수 있습니다. 속성이 필요한 방법은 검색 가능으로 표시된 속성만을 받아들입니다. 가능한 집계 방법은 다음과 같습니다:
.count()
는 각 버킷의 오브젝트 수를 반환합니다..average()
는 주어진 숫자, 타임스탬프, 날짜 속성의 평균 수를 반환합니다..max()
는 주어진 숫자, 타임스탬프, 날짜 속성의 최대값을 반환합니다..min()
는 주어진 숫자, 타임스탬프, 날짜 속성의 최소값을 반환합니다..sum()
는 주어진 숫자 속성의 값의 합계를 반환합니다..cardinality()
는 주어진 속성에 대한 구별되는 값의 대략적인 수를 반환합니다.이러한 방법 중 하나를 호출하면 TwoDimensionalAggregation
또는 ThreeDimensionalAggregation
이 반환됩니다. 최종 집계 방법 중 하나를 호출하기 전에 .segmentBy()
를 호출한 경우 ThreeDimensionalAggregation
이 반환됩니다.
유효한 버킷 유형을 포함한 이러한 집계 유형의 구조에 대해 더 알아보기.
결과 집계는 원격 서비스에서 데이터를 로드해야 하므로 Promise
로 감싸져 있다는 점에 유의하세요. Promise
결과를 풀어내기 위해 async/await 구문을 사용할 수 있습니다.
아래는 집계를 로드하고 결과로 반환하는 전체 예제입니다.
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
import { Function, ThreeDimensionalAggregation } from "@foundry/functions-api"; import { Objects } from "@foundry/ontology-api"; export class AggregationFunctions { // 직책과 사무실별 직원 수를 집계하는 함수 @Function() public async employeesByRoleAndOffice(): Promise<ThreeDimensionalAggregation<string, string>> { return Objects.search() .employee() // 직책별로 그룹화 .groupBy(e => e.title.topValues()) // 사무실별로 세분화 .segmentBy(e => e.office.topValues()) // 카운트 계산 .count(); } }
다음은 groupBy 문 없이 집계하는 전체 예제입니다:
Copied!1 2 3 4 5 6 7 8 9 10
import { Function } from "@foundry/functions-api"; import { Objects } from "@foundry/ontology-api"; export class AggregationFunctions { @Function() public async employeesStats(): Promise<Double> { // 모든 직원의 수를 세고, count()가 undefined를 반환하면 기본값으로 0을 반환합니다. return Objects.search().employee().count() ?? 0; } }
위의 코드 예제에서 적절한 라인을 교체하여 groupBy 없이 다른 집계도 수행할 수 있습니다. 예를 들면:
Objects.search().employee().count();
(위의 예제에서 볼 수 있음)Objects.search().employee().average(e => e.tenure);
Objects.search().employee().max(e => e.tenure);
Objects.search().employee().min(e => e.tenure);
Objects.search().employee().sum(e => e.salary);
Objects.search().employee().cardinality(e => e.office);
메모리에서 집계 결과를 조작하는 예제는 맞춤형 집계 생성 가이드를 참조해보세요.