위치:
Apex 데이터 쿼리 보관
아카이브 Apex 데이터 쿼리는 아카이브 앱에서 아카이브된 데이터에 대한 프로그래밍 방식의 액세스를 지원합니다. 해당 데이터 쿼리는 비즈니스 프로세스를 자동화하고, 타사 시스템 통합을 지원하며, 사용자 정의 보기 및 보고서를 만들고, 활성 레코드와 함께 보관된 데이터를 교차 참조합니다.
보관 구성 요소 및 보관 검색은 수동 데이터 검색 옵션을 제공합니다. Apex 코드를 통해 직접 데이터에 액세스할 수 있는 쿼리 매개 변수, 필터, 페이지 매김과 같은 고급 기능을 제공합니다.
Apex 데이터 쿼리 기능은 다음과 같습니다.
- 지정된 기준을 사용하여 보관된 레코드를 검색합니다.
- 별표와 부분 일치(*)를 사용합니다.
- 페이지당 최대 1,000개의 레코드를 배치로 대규모 데이터 집합을 반환합니다.
- 최대 6개의 필터를 적용하여 결과를 구체화합니다.
- 프로덕션 조직에서 개체가 삭제된 경우에도 보관된 레코드를 쿼리합니다.
이러한 시스템 관련 Salesforce 개체는 필터링되며 Apex 통해 검색할 수 없습니다.
FeedHistoryRelationShare
최적의 성능을 유지하고 관련 보관된 데이터만 반환되도록 하기 위해 보관에서 해당 개체를 검색에서 제외합니다.
보관된 파일에 액세스하려면 보관 구성 요소 또는 보관 검색을 사용합니다.
Apex 보관은 다음 요청 제한을 적용합니다.
| 간격 | 요청 제한 |
|---|---|
| 분당 | 1,000 |
| 시간당 | 30,000 |
| 일별 | 100,000 |
이 제한을 초과하면 HTTP 상태 코드 429가 수신됩니다.
아카이빙 Apex 데이터 쿼리 방법
보관된 데이터를 쿼리하는 방법을 정의하려면 Archive Apex 제공하는 방법을 설정합니다.
- 보관 데이터 액세스 -
ArchiverAccessor내의 메서드가 보관된 레코드와 상호 작용하도록 설계되었습니다. 그런 다음, 쿼리를 구축하고 아카이브 제품에 저장된 데이터를 검색할 수 있습니다. - 쿼리 작업 정의 - 이러한 서명은 전역 검색 및 필터링된 쿼리와 같이 Apex 사용하여 수행할 수 있는 쿼리 유형을 알려줍니다.
- 안내 사용량 - 개발자는 메서드 서명을 검사하여 구현에 필요한 입력 및 출력을 이해할 수 있습니다.
performArchiverGlobalSearch 방법
이 메서드는 보관된 데이터에서 전역 검색을 수행하는 기능을 나타냅니다.
Query 매개 변수
Apex 데이터 쿼리는 몇 가지 매개 변수를 사용하여 검색을 세분화합니다. 일부 매개 변수는 필수이며, 다른 매개 변수는 선택 사항입니다. 각 매개 변수를 구성하는 방법을 이해하면 가장 정확하고 관련성이 높은 결과를 얻을 수 있습니다.
- 개체 이름 - 쿼리할 Salesforce 개체의 유형을 지정합니다.
예를 들어,
string sObjectName = 'Account'은 쿼리가 계정 레코드를 대상으로 지정합니다.이 매개 변수는 필수입니다.
노트 각 쿼리는 단일 개체를 대상으로 합니다. 별도의 쿼리를 사용하여 여러 개체에서 데이터를 검색합니다. - 검색 필터 - 필드 조건을 기반으로 검색 결과의 범위를 좁힙니다.
- 필드 이름 -
Name또는CreatedDate과 같이 필터링하려는 필드입니다. - 값 또는 값 목록 - 일치시킬 특정 값 또는 값
예: 단일 값 필터
SF_Archive.SearchFilter filter = new SF_Archive.SearchFilter('Name', 'test');이 쿼리는 이름 필드가 문자열 "test"과 일치하는 레코드를 반환합니다.
예: 다중 값 필터SF_Archive.SearchFilter filter = new SF_Archive.SearchFilter('Status', new List<String>{'Open', 'Closed'});이 쿼리는 상태 필드가 문자열 "열림" 또는 "마감됨"과 일치하는 레코드를 반환합니다.
빈 값 또는 Null 값 처리 - 필드가 비어 있거나 null인 레코드를 검색하려면 빈 문자열("")을 값 목록에 추가합니다.예:
이 쿼리는 제목 필드가 비어 있거나 null인 사례 레코드를 반환합니다.List<SearchFilter> filters = new List<SearchFilter>(); filters.add(new SearchFilter('Subject', ''));검색 필터 제한:
- 쿼리에는 쿼리당 하나 이상의 필터가 필요합니다.
- 쿼리당 최대 6개의 필터가 있을 수 있으며,
AND논리와 결합됩니다. - 필터는 기본적으로
AND논리를 사용하여 결합됩니다.OR논리는 현재 지원되지 않습니다. - 필터의 값 목록은 1,000개 항목을 초과할 수 없습니다.
이 매개 변수는 필수입니다.
- 필드 이름 -
- 날짜 필터 - 날짜를 기반으로 검색하려면
DateRange매개 변수와 필수 필터를 사용합니다.DateRange은ArchiveDate,CreatedDate또는ModifiedDate과 같은 필드로 레코드를 필터링합니다.예: 특정 날짜 쿼리에 대한 날짜 필터
Date todayDate = Date.today(); Date jan1st2024 = Date.newInstance(2024, 1, 1); DateRange dateRange = new DateRange('archive_date', jan1st2024, todayDate);이 쿼리는 2024년 1월 1일부터 오늘 사이에 보관된 레코드를 반환합니다.
예: 다중 날짜 범위의 날짜 필터
List<SF_Archive.SearchFilter> filters = new List<SF_Archive.SearchFilter>(); SF_Archive.SearchFilter filter = new SF_Archive.SearchFilter('Name', 'test'); filters.add(filter); string sObjectName = 'Account'; Date myDate = Date.newInstance(2024, 1, 11); // January 11, 2024 Date myDate2 = Date.newInstance(2023, 12, 25); // December 12, 2023 SF_Archive.dateRange range = new SF_Archive.dateRange('CreatedDate', myDate, myDate); SF_Archive.dateRange range2 = new SF_Archive.dateRange('CreatedDate', myDate2, myDate2); list<SF_Archive.dateRange> ranges = new list<SF_Archive.dateRange> {range, range2}; SF_Archive.ArchiverAccessorResponse res = SF_Archive.ArchiverAccessor.performArchiverGlobalSearch(sObjectName, filters, ranges);이 쿼리는 2023년 12월 12일~2024년 1월 11일 사이에 보관된 레코드를 반환합니다.
날짜 필터 권장 사항:
- 보관 날짜를 기반으로 검색하려면
archive_date날짜 필드를 추가합니다. - Apex 날짜 형식을 사용합니다. MM/DD/YYYY.
이 매개 변수는 선택적입니다.
- 보관 날짜를 기반으로 검색하려면
- 반환된 필드 - 결과에 포함할 필드를 지정합니다. 지정되지 않은 경우 모든 필드가 반환됩니다.
예: 특정 필드 반환
List<string> fields = new List<string>{'Name', 'CreatedDate'};이 쿼리는 각 레코드에 대한
Name및CreatedDate필드만 반환합니다.이 매개 변수는 선택적입니다.
- 페이지 크기 - 쿼리당 레코드 수를 설정합니다. 쿼리당 기본 레코드 수는 25개이며 최대값은 1,000개입니다.
예: 사용자 정의 페이지 크기
SF_Archive.ArchiverAccessorResponse res = SF_Archive.ArchiverAccessor.performArchiverGlobalSearch('Account', filters, 100, fields);이 쿼리는 페이지당 100개의 레코드를 반환합니다.
이 매개 변수는 선택적입니다.노트 쿼리의 레코드가 1,000개를 초과하면 런타임 오류가 트리거됩니다. - 정렬 방향 -
CreatedDate등 필드별로 결과를 정렬합니다.- 오름차순(
asc): 가장 오래된 항목부터 최신 항목까지 - 내림차순(
desc): 최신 항목에서 가장 오래된 항목으로 표시됩니다.예: 정렬 쿼리
SortingDirection sortingDirection = new SortingDirection('desc');이 쿼리는
CreatedDate에 따라 내림차순으로 정렬된 레코드를 반환합니다.이 매개 변수는 선택적입니다.
- 오름차순(
getNextPage 방법
결과가 모두 동일한 페이지에 맞지 않을 경우 이 메서드는 다음 페이지를 호출합니다.
ScrollId 매개 변수
페이지 매김을 사용하여 최대 1,000개의 레코드 페이지에서 결과를 가져와 대규모 데이터 집합을 반환합니다.
페이지 매김 워크플로를 설정하려면 초기 쿼리를 수행하고 응답에서 scrollId를 사용하여 후속 페이지를 가져오고 scrollId = '-1'.까지 계속합니다.
예: 페이지 매김으로 결과 가져오기
// Perform initial search query
SF_Archive.ArchiverAccessorResponse res = SF_Archive.ArchiverAccessor.performArchiverGlobalSearch('Account',
filters, 100, fields);
// Get the search response
SF_Archive.ArchiverAccessorSearchResponse searchResponse = res.getSearchResponseMap();
// Process first page of results
system.debug('Total result count: ' + searchResponse.totalResultCount);
system.debug('Records: ' + searchResponse.records);
// Fetch next page using the scrollId
if (searchResponse.scrollId != '-1') {
SF_Archive.ArchiverAccessorResponse nextPageRes = SF_Archive.ArchiverAccessor.getNextPage(searchResponse.scrollId);
SF_Archive.ArchiverAccessorSearchResponse nextPageResponse = nextPageRes.getSearchResponseMap();
system.debug('Next Page Records: ' + nextPageResponse.records);
}메서드 액세스
메서드 서명을 찾으려면 설정에서 빠른 찾기 상자에 Apex 클래스를 입력한 후 Apex 클래스를 선택합니다. ArchiverAccessor 수업을 엽니다. performArchiverGlobalSearch 네임스페이스 아래에 나열된 모든 메서드를 찾습니다.
샘플 데이터 쿼리
이 예에서는 다음 조건을 사용하여 Account 레코드를 검색합니다.
- 필드:
Name,CreatedDate - 제한: 페이지당 100개의 레코드
- 이름: 문자열 "test" 포함
- 정렬: 내림차순
CreatedDate
List<SF_Archive.SearchFilter> filters = new List<SF_Archive.SearchFilter>();
SF_Archive.SearchFilter filter = new SF_Archive.SearchFilter('Name', 'test');
filters.add(filter);
List<string> fields = new List<string>{'Name', 'CreatedDate'};
SortingDirection sortingDirection = new SortingDirection('desc');
SF_Archive.ArchiverAccessorResponse res = SF_Archive.ArchiverAccessor.performArchiverGlobalSearch('Account',
filters, 100, fields, sortingDirection);
일반적인 오류 문제 해결
| 오류 코드 | 설명 | 해결 방법 |
|---|---|---|
INTERNAL_ERROR |
예기치 않은 실패가 발생했습니다. | 오류 세부 사항은 지원에 문의하십시오. |
RESOURCE_LIMIT_ERROR |
페이지 매김 또는 쿼리 크기 제한을 초과했습니다. | 페이지 크기를 줄이거나 검색 필터를 세분화합니다. |
VALIDATION_ERROR |
검색 기준이 누락되었거나 잘못되었습니다. | 모든 필드 및 필터가 유효한지 확인합니다. |
추가 권장 사항
- API 사용을 모니터링하여 제한에 도달하지 않도록 합니다.
- 개체에 응답을 캐스팅하려면 해당 응답을 JSON으로 직렬화한 다음, 다시 개체로 역직렬화합니다.
- 필드가 활성화되고 액세스할 수 있는지 확인합니다.
- 모든 쿼리 매개 변수를 다시 확인합니다.
- 해결되지 않은 문제는 자세한 로그와 함께 Salesforce 지원에 문의하십시오.
단계별 테스트 절차는 아카이브 Apex 테스트를 참조하십시오.
- Apex 데이터 쿼리 보관 - 코드 예제
이 코드 예에서 필터, 날짜 범위 및 보관 검색 요청은 보관 앱의 상태 코드를 통해 확인됩니다. - Apex 데이터 쿼리 보관 - 샘플 사용 사례 1
이 예제 사용 사례는 아카이브 앱에서 우선 순위가 높은 계정을 표시하는 구성 요소를 구축하고 사용자 정의하는 방법을 보여줍니다. - Apex 데이터 쿼리 보관 - 샘플 사용 사례 2
이 예제 사용 사례는 아카이브 앱에서 아카이브 Apex CPU 제한 또는 시간 초과 콜아웃과 같은 총괄자 제한을 초과하지 않고 과업을 처리하는 방법을 보여줍니다.
Apex 데이터 쿼리 보관 - 코드 예제
이 코드 예에서 필터, 날짜 범위 및 보관 검색 요청은 보관 앱의 상태 코드를 통해 확인됩니다.
(scrollId != -1) 이후의 getNextPage 호출은 결과 크기가 performArchiverGlobalSearch 호출에서 제한되므로 포함됩니다.
string sObjectName = 'Account';
list<SF_Archive.SearchFilter>request = new list<SF_Archive.SearchFilter>();
SF_Archive.SearchFilter filter1 = new SF_Archive.SearchFilter('Name', 'test');
request.add(filter1);
SF_Archive.dateRange range = new SF_Archive.dateRange('CreatedDate', system.today()-150, system.today());
SF_Archive.ArchiverAccessorResponse res = SF_Archive.ArchiverAccessor.performArchiverGlobalSearch(sObjectName, request, range);
if(res.getStatusCode() == 200){
system.debug('code: ' + res.getStatuscode());
SF_Archive.ArchiverAccessorSearchResponse searchResponse = res.getSearchResponseMap();
system.debug('count: '+ searchResponse.totalResultCount);
system.debug('scrollid: '+ searchResponse.scrollId);
system.debug('list size: '+ searchResponse.records.size());
string scrollId = searchResponse.scrollId;
integer page = 1;
while(scrollId != '-1'){
page++;
SF_Archive.ArchiverAccessorResponse secondPage =
SF_Archive.ArchiverAccessor.getNextPage(searchResponse.scrollId);
if(secondPage.getStatusCode() == 200){
SF_Archive.ArchiverAccessorSearchResponse searchResponse2 = secondPage.getSearchResponseMap();
scrollId = searchResponse2.scrollId;
system.debug('count: '+ searchResponse2.totalResultCount);
system.debug('scrollid: '+ searchResponse2.scrollId);
system.debug('list size: '+ searchResponse2.records.size());
system.debug('page number: '+ page);
} else{
system.debug('response is != 200: '+ secondPage.getStatusCode());
system.debug('body: '+ secondPage.getBody());
break;
}
}
} else {
system.debug('status code erorr|: '+ res.getStatusCode());
system.debug('status code message|: '+ res.getErrorMessage());
}Apex 데이터 쿼리 보관 - 샘플 사용 사례 1
이 예제 사용 사례는 아카이브 앱에서 우선 순위가 높은 계정을 표시하는 구성 요소를 구축하고 사용자 정의하는 방법을 보여줍니다.
사용 사례
비즈니스에서는 계층 3 지원 팀이 우선 순위가 높은 보관된 사례를 보려면 액세스 권한이 있어야 합니다.
이 예는 다음을 보여줍니다.
- 사용자 정의된 Lightning 웹 구성 요소(LWC)를 만듭니다.
- Apex 데이터 쿼리를 사용하여 보관된 데이터를 가져옵니다.
- 필터(우선 순위가 높음)를 적용합니다. 노트 기타 필터는 Archive Apex Data Queries — Code Example에서 코드를 참조하여 사용자 정의할 수 있습니다.
이 예는 레코드 25개로 제한됩니다. Apex 사용하면 페이지당 결과를 1,000개로 설정할 수 있습니다. 기본값은 25이며 결과를 통해 페이지 매김 옵션이 있습니다.
우선 순위가 높은 사례를 표시하는 구성 요소
샘플 SdkUseCaseWidget.js
이 코드 예에서 매개 변수는 AccountRecordId입니다.
import { LightningElement, api, track } from 'lwc';
import getCases from '@salesforce/apex/ArchiveSdk.getCases';
export default class SampleSdkUseCaseWidget extends LightningElement {
@api recordId;
columns = [
{ label: 'Case Number', fieldName: 'caseNumber', type: 'text', cellAttributes: {alignment: 'center'}},
{ label: 'Subject', fieldName: 'subject', type: 'text' , cellAttributes: {alignment: 'center'}, },
{ label: 'Priority', fieldName: 'priority', type: 'text', cellAttributes: {alignment: 'center'}, },
{ label: 'Status', fieldName: 'status', type: 'text', cellAttributes: {alignment: 'center'}, }
];
@track records;
@track data
@track _loading;
async connectedCallback() {
this._loading = true;
try {
const result = await getCases({parentId: this.recordId})
this.records = result;
this._loading = false;
} catch (error) {
this._loading = false;
}}
} 샘플 SdkUseCaseWidget.html
LWC에서 사용하는 Apex 컨트롤러가 Apex 데이터 쿼리를 호출합니다.
SF_Archive.ArchiverAccessor.performArchiverGlobalSearch(sObjectName, request, fields, range);이는 Apex 보관 호출입니다. 다음 매개 변수를 포함합니다.
- sObjectName - 검색을 표시합니다.
- 필터 - 데이터를 검색하는 데 사용됩니다.
- 필드 - 데이터에서 반환될 예상 필드입니다.
- 범위 - 데이터를 쿼리하는 데 사용되는 날짜 범위입니다.
<template>
<template if:true={_loading}>
<lightning-spinner></lightning-spinner>
</template>
<lightning-datatable
key-field="caseNumber"
data={records}
columns={columns}
hide-checkbox-column>
</lightning-datatable>
</template>ArchiveSdk.cls
이 코드 블록은 Apex 컨트롤러입니다.
public with sharing class ArchiveSDK {
@AuraEnabled
public static List<CaseTableWrapperExample.CaseRecord> getCases(String parentId) {
// Create an empty list to hold maps with String keys and Object values
List<Map<String, Object>> totalRecords = new List<Map<String, Object>>();
// Create a list to store search filter objects
List<SF_Archive.SearchFilter> request = new List<SF_Archive.SearchFilter>();
// Create a search filter for the 'AccountId' field with a given 'parentId' value
SF_Archive.SearchFilter filter1 = new SF_Archive.SearchFilter('AccountId', parentId);
// Create a search filter for the 'Priority' field with a given 'High' value
SF_Archive.SearchFilter filter2 = new SF_Archive.SearchFilter('Priority', 'High');
// Add the filters to the request list
request.add(filter1);
request.add(filter2);
// Define the object name as 'Case'
String sObjectName = 'Case';
// Create a list of Strings representing field names to be retrieved from Archive DB
List<String> fields = new List<String>{'CaseNumber', 'Subject', 'Priority', 'Status'};
// Create the DateRange based on the created date
SF_Archive.DateRange range = new SF_Archive.DateRange('CreatedDate', system.today() - 150, system.today());
// Perform an initial global search and store the response
SF_Archive.ArchiverAccessorResponse res = SF_Archive.ArchiverAccessor.performArchiverGlobalSearch(sObjectName, request, range);
// Check if the HTTP response status code is 200 (success)
if (res.getStatusCode() == 200) {
system.debug('code: ' + res.getStatuscode());
// Retrieve the initial search response map
SF_Archive.ArchiverAccessorSearchResponse searchResponse = res.getSearchResponseMap();
system.debug('count: ' + searchResponse.totalResultCount);
system.debug('scrollid: ' + searchResponse.scrollId);
system.debug('list size: ' + searchResponse.records.size());
// Store the scroll ID for pagination
String scrollId = searchResponse.scrollId;
// Initialize the page number
Integer page = 1;
// Add the records from the initial search to the totalRecords list
totalRecords.addAll(searchResponse.records);
// Continue to fetch additional pages while the scroll ID is not '-1'
while (scrollId != '-1') {
page++;
// Get the next page of search results using the UPDATED scrollId
SF_Archive.ArchiverAccessorResponse nextPageResponse = SF_Archive.ArchiverAccessor.getNextPage(scrollId);
// Check if the HTTP response status code is 200 (success)
if (nextPageResponse.getStatusCode() == 200) {
// Retrieve the search response for the current page
SF_Archive.ArchiverAccessorSearchResponse searchResponse2 = nextPageResponse.getSearchResponseMap();
// CRITICAL FIX: Update the scrollId with the value from the new response
scrollId = searchResponse2.scrollId;
system.debug('count: ' + searchResponse2.totalResultCount);
system.debug('scrollid: ' + searchResponse2.scrollId);
system.debug('list size: ' + searchResponse2.records.size());
system.debug('page number: ' + page);
// Add the records from the current page to the totalRecords list
totalRecords.addAll(searchResponse2.records);
} else {
// Output an error message if the HTTP response status code is not 200
system.debug('response is != 200: ' + nextPageResponse.getStatusCode());
system.debug('body: ' + nextPageResponse.getBody());
// Break out of the loop if there is an error
break;
}
} // End of while loop
} else {
// Handle error from initial search
system.debug('status code error: ' + res.getStatusCode());
system.debug('status code message: ' + res.getErrorMessage());
}
// Return the list of total records
List<CaseTableWrapperExample.CaseRecord> result = new List<CaseTableWrapperExample.CaseRecord>();
return CaseTableWrapperExample.getCasesTable(totalRecords);
}
}CaseTableWrapperExample.cls
Apex LWC로 클래스를 수식화하는 도우미 클래스
public class CaseTableWrapperExample{
public static List<caseRecord> getCasesTable(list<map<string,object>> cases){
List<caseRecord> caseReturnList = new List<caseRecord>();
for(Map<string,object> caseRecord: cases){
caseRecord tempCase = new caseRecord();
tempCase.caseNumber = String.valueOf(caseRecord.get('CaseNumber'));
tempCase.id = String.valueOf(caseRecord.get('Id'));
tempCase.origin = String.valueOf(caseRecord.get('Origin'));
tempCase.status = String.valueOf(caseRecord.get('Status'));
tempCase.subject = String.valueOf(caseRecord.get('Subject'));
tempCase.priority = String.valueOf(caseRecord.get('Priority'));
caseReturnList.add(tempCase);
}
return caseReturnList;
}
public class caseRecord {
@AuraEnabled public string caseNumber;
@AuraEnabled public string id;
@AuraEnabled public string origin;
@AuraEnabled public string status;
@AuraEnabled public string priority;
@AuraEnabled public string subject;
}}위 코드는 Lightning 페이지에 LWC를 구성 요소로 추가할 수 있는 샘플 시나리오를 설명합니다.
실제 Lightning 데이터 테이블을 보려면 이 코드를 sampleSdkUseCaseWidget.js-meta.xml 파일에 추가합니다. 그런 다음, Lightning 페이지에 보관 구성 요소를 추가합니다.
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="<a href='http://soap.sforce.com/2006/04/metadata">;
<apiVersion>55.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__RecordPage</target>
<target>lightning__AppPage</target>
</targets>
<targetConfigs>
<targetConfig targets="lightning__RecordPage">
<supportedFormFactors>
<supportedFormFactor type="Small" />
<supportedFormFactor type="Large" />
</supportedFormFactors>
</targetConfig>
<targetConfig targets="lightning__AppPage">
<supportedFormFactors>
<supportedFormFactor type="Small" />
<supportedFormFactor type="Large" />
</supportedFormFactors>
</targetConfig>
</targetConfigs>
</LightningComponentBundle>Apex 데이터 쿼리 보관 - 샘플 사용 사례 2
이 예제 사용 사례는 아카이브 앱에서 아카이브 Apex CPU 제한 또는 시간 초과 콜아웃과 같은 총괄자 제한을 초과하지 않고 과업을 처리하는 방법을 보여줍니다.
자세한 내용은 Apex 총괄자 제한을 참조하십시오.
사용 사례
비즈니스에서는 계층 3 지원 팀이 우선 순위가 높은 보관된 사례를 보려면 액세스 권한이 있어야 합니다.
이 예는 Apex 통해 검색된 보관된 레코드 수가 너무 많을 경우 오류를 해결하는 방법을 보여줍니다. 오류: SF_Archive.ArchiverAccessor.ArchiverAccessorException: Exceeded time
allotted for callout, please contact support를 참조하세요.
이러한 Apex 클래스의 코드가 이 사용 사례를 만듭니다.
ArchiveSecondPageJob 클래스는 스크롤 ID를 사용하여 아카이브에서 페이지가 매겨진 데이터를 처리하고 필요에 따라 콜아웃을 만듭니다. 대기 가능 인터페이스를 통해 비동기식으로 실행되며, 제한을 초과하지 않도록 총 실행 시간을 추적하고 필요한 경우 계속 처리하기 위해 대기열에 지정합니다. 클래스는 응답을 처리하고 스크롤 ID를 업데이트하며 검색된 각 데이터 페이지에 대한 세부 사항을 기록합니다.
public class ArchiveSecondPageJob implements Queueable,Database.AllowsCallouts {
private String scrollId;
private long totalTime;
private integer pageNumber;
public archiveSecondPageJob(String prevScrollId, integer pageNumber) {
scrollId = prevScrollId;
this.pageNumber = pageNumber;
}
public void execute(QueueableContext context) {
system.debug('executing');
doExecute();
}
private void doExecute() {
SF_Archive.ArchiverAccessorSearchResponse searchResponse = null;
integer page = 1;
long totalTime = 0;
while(scrollId != '-1')
{
//avoid 12000 ms limit
if(totalTime > 90000){
system.debug('Creating new task');
archiveSecondPageJob q = new archiveSecondPageJob(scrollId,this.pageNumber);
System.enqueueJob(q);
return;
}
//Get the next page using the scrollId
Long startTime = DateTime.now().getTime();
SF_Archive.ArchiverAccessorResponse nextPage = SF_Archive.ArchiverAccessor.getNextPage(scrollId);
Long stopTime = DateTime.now().getTime();
totalTime += stopTime - startTime;
if(nextPage.getStatusCode() == 200){
this.pageNumber++;
SF_Archive.ArchiverAccessorSearchResponse searchResponse2 =nextPage.getSearchResponseMap();
scrollId = searchResponse2.scrollId;
system.debug('count: '+ searchResponse2.totalResultCount);
system.debug('scrollid: '+ searchResponse2.scrollId);
system.debug('list size: '+ searchResponse2.records.size());
system.debug('body: '+ searchResponse2.records);
system.debug('page: '+ pageNumber);
system.debug('time: '+ totalTime);
}
else{
system.debug('response is != 200: '+ nextPage.getStatusCode());
system.debug('body: '+ nextPage.getBody());
return;
}
}
}
}
ArchiveSearch 클래스는 특정 필터를 사용하여 사례 개체에 대한 검색을 수행하고 결과를 검색하고 총 개수 및 스크롤 ID와 같은 세부 사항을 기록합니다. 검색에서 더 많은 결과 페이지를 나타내는 유효한 스크롤 ID를 반환하면 다음 페이지를 비동기식으로 처리하도록 archiveSecondPageJob를 대기열에 지정합니다. 이 클래스는 본질적으로 검색을 시작하고 이전에 정의된 archiveSecondPageJob에 추가 처리를 전달합니다.
다음은 초기 검색 호출의 형식입니다.
public class ArchiveSearch {
public void doSearch(){
string sObjectName = 'Case';
list<SF_Archive.SearchFilter> request = new list<SF_Archive.SearchFilter>();
SF_Archive.SearchFilter filter1 = new SF_Archive.SearchFilter('Priority', 'High');
request.add(filter1);
list<string> fields = new list<string>{'CaseNumber', 'Id'};
SF_Archive.ArchiverAccessorResponse res = SF_Archive.ArchiverAccessor.performArchiverGlobalSearch(sObjectName, request, fields);
if(res.getStatusCode() == 200){
system.debug('code: ' + res.getStatuscode());
SF_Archive.ArchiverAccessorSearchResponse searchResponse = res.getSearchResponseMap();
system.debug('count: '+ searchResponse.totalResultCount);
system.debug('scrollid: '+ searchResponse.scrollId);
system.debug('list size: '+ searchResponse.records.size());
string scrollId = searchResponse.scrollId;
integer page = 1;
if(scrollId != '-1'){
system.debug('calling next page');
integer pageNumber = 2;
archiveSecondPageJob q = new archiveSecondPageJob(scrollId, pageNumber);
System.enqueueJob(q);
}}}}자세한 내용은 Salesforce Apex 개발자 가이드를 참조하십시오.

