서브 그래프 개발, 파트 2 : 배열 처리 및 엔티티 식별

(ProtoFire.io)

(1 부 ) | 2 부

이 블로그 게시물은 배열을 효율적으로 사용하고 생성하는 방법에 대한 실질적인 권장 사항을 제공합니다. 고유하고 참조 가능한 엔티티 ID입니다.

이 시리즈의 1 부에서는 개발자가 기본 구조를 이해하는 데 도움이되도록 하위 그래프에 대한 개요를 제공했습니다. 또한 데이터 매핑 및 집계에 대한 통찰력도 공유했습니다.

이번에는 고유하고 쉽게 참조 할 수있는 항목에 대한 배열 처리 및 ID 생성이라는 또 다른 두 가지 주제에 대해 설명합니다. 토론의 일환으로 배열을 효율적으로 관리하고 항목의 이름을 올바르게 지정하는 방법에 대한 권장 사항을 제공합니다.

효율적으로 배열 처리

항목에 배열을 추가하는 것은 특정 시나리오에서 유용합니다. 예를 들어 데이터 소스의 주소 목록을 모델링하거나 시간 경과에 따른 특정 필드의 과거 변화를 추적해야하는 경우가 있습니다.

배열이 하위 그래프 내에서 작동하는 방식에 대한 사전 지식이 없으면 고려할 수 있습니다. 엔티티 유형 정의 (schema.graphql 파일 내)에 배열 유형의 필드를 만들고 동일한 유형의 새 엔티티가 생성 될 때마다 빈 배열을 초기화합니다. 새 데이터가 배열에 추가되면 데이터를 푸시하고 엔티티를 저장할 수 있습니다. 직관적으로 들리지만 안타깝게도 작동하지 않습니다.

특히 위의 시나리오에서 하위 그래프의 배열을 수동으로 처리하는 경우 몇 가지주의 사항이 있습니다. 엔티티의 배열에 액세스 할 때마다 실제로 얻는 것은 배열의 사본입니다. 따라서 새 데이터를 추가하고 엔터티를 저장하면 원본은 변경되지 않고 배열의 복사본 만 수정하기 때문에 예상대로 작동하지 않습니다.

업데이트를 위해 실제 배열의 경우 배열의 복사본을 변수에 배치 한 다음 데이터를 수정할 수 있습니다. 다음으로 변수를 엔티티의 새 배열로 설정할 수 있습니다. 이렇게하면 이전 어레이가 복사본으로 대체됩니다. 이 배열 업데이트 프로세스는 다음 코드에 예시되어 있습니다.

// This won"t work
entity.numbers.push(BigInt.fromI32(1))
entity.save()// This will work
let numbers = entity.numbers
numbers.push(BigInt.fromI32(1))
entity.numbers = numbers
entity.save()

위에 설명 된 방식으로 배열을 업데이트 할 수 있지만 이상적인 솔루션은 아닙니다. . 불편 함 외에도 어레이를 수동으로 처리하지 않는 또 다른 이유가 있습니다. 시간 여행 쿼리입니다. (시간 여행 쿼리에 대해 자세히 알아 보려면 시리즈의 1 부를 읽으십시오.)

서브 그래프는 모든 항목을 표시하는 모든 항목의 모든 변경 사항을 추적하기 때문에 시간 여행 쿼리 만 수행 할 수 있습니다. 시각. 크고 자주 업데이트되는 배열 필드가있는 엔터티가 많은 경우 모든 배열의 복사본도 저장해야합니다. 이렇게하면 하위 그래프를 인덱싱하는 인덱서의 성능과 디스크 공간에 큰 타격을줍니다.

현재 The Graph의 호스팅 서비스는 사용할 수있는 유일한 활성 인덱서입니다. 앞으로 더 많은 인덱서가 The Graph의 분산 네트워크를 추가하여 참여할 수 있습니다. 이 새로운 인덱서는 인덱싱 할 하위 그래프를 선택할 수 있습니다. 배열로 인해 하위 그래프가 제대로 최적화되지 않은 경우 인덱서에서 선택하지 않을 가능성이 높습니다.

배열을 최적화하려면 @derivedFrom 주석. 이 메서드를 사용하면 엔티티 유형에 정의 된 모든 배열 필드가 정의중인 엔티티에 연결된 지정된 유형의 모든 엔티티에 의해 자동으로 채워집니다. 다음 예는 @derivedFrom 주석의 사용법을 보여줍니다.

type User @entity {
id: ID! positions: [Position!]! @derivedFrom(field: “user”)
}type Position @entity {
id: ID! user: User! # This is the ID String of the User
}

위의 예에는 사용자가 있습니다. 자동 생성 된 Position 항목 목록이 있습니다. 하위 그래프가 User 항목의 위치 필드를 묻는 쿼리를 수신 할 때마다 하위 그래프는 모든 Position 유형 항목에 대해 역방향 조회를 수행합니다. user 필드의 특정 User 항목에 연결됩니다. 이러한 방식으로 연결된 엔티티는 필드 중 하나에 다른 엔티티의 문자열 ID가있는 엔티티입니다.

@derivedFrom 주석을 사용하여 엔티티를 정의 할 수 있습니다. 배열 데이터에 대해 원하는 유형을 지정하고, 배열을 파생 할 때 사용되는 필드를 정의하고, ID를 통해 원래 엔티티에 연결합니다. 어레이 데이터를 나타내는 엔터티에 더 많은 데이터 (예 : 메타 데이터 생성 또는 업데이트)를 추가 할 수 있다는 이점도 있습니다. 이들은 완전한 엔티티이므로 배열에서 조회하는 대신 ID를로드하여 쉽게 업데이트 할 수 있습니다.

@derivedFrom 주석으로 배열을 처리하는 동안 더 쉽습니다. 여전히 몇 가지 고려해야 할 사항이 있습니다.첫째, 일대 다 관계에서만 작동합니다. 다 대다 관계에서 배열을 수동으로 처리하려면 방정식의 한쪽이 여전히 필요합니다. 둘째, 쿼리 할 때 배열이 채워 지므로 하위 그래프가 인덱싱되는 동안에는 배열 데이터에 액세스 할 수 없습니다.

이름 지정 만들기 엔티티 ID에 대한 규칙

schema.graphql 파일에 정의 된 모든 엔티티는 다음과 같은 ID 필드로 식별됩니다. 문자열로 표현되는 ID! 유형으로 선언됩니다. ID 필드는 항목을로드, 생성 및 저장하는 데 사용되므로 중요합니다.

ID 필드는 항목을 식별하는 기본 수단이므로 항상 고유해야합니다. 즉, ID의 고유성을 보장하는 것은 어렵지 않습니다. 인덱스 시간 동안 존재하는 데이터를 결합하여 고유 한 ID를 생성 할 수 있습니다. 다음 코드는 이에 대한 예입니다.

event.transaction.hash.toHex() + "-" + 
event.logIndex.toString()

이벤트의 트랜잭션 해시 (다른 트랜잭션에 대해 고유함)를 가져 와서 로그 인덱스에 추가하여 특정 이벤트 (트랜잭션 내에서 이벤트를 식별)에 대해 고유 한 복합 ID를 생성 할 수 있습니다. 이러한 방식으로 단일 이벤트에 대해 단일 엔티티 만 생성 된 경우 동일한 유형의 다른 엔티티 중에서 특정 엔티티를 식별 할 수 있습니다. 필요한 경우 더 많은 데이터를 추가하여 동일한 이벤트에서 생성 된 개체 수를 고유하게 식별 할 수도 있습니다. 예를 들어 엔터티가 생성 될 때마다 카운터를 설정하고 새로 생성 된 엔터티에 값을 추가 할 수 있습니다.

엔티티의 고유 ID를 쉽게 생성 할 수있는 방법이 있으면 편리하지만 또한해야합니다. 예측 가능하고 참조 할 수있는 ID를 생성하기 위해 노력합니다. 최종 사용자가 ID를 통해 쿼리 할 가능성이있는 도메인의 일부와 관련된 엔티티가있는 경우 작업중인 도메인을 참조하는 ID를 생성 할 수 있습니다.

예를 들면 다음과 같습니다. DEX 하위 그래프에 Account 항목을 만드는 시나리오입니다. 이 Account 항목은 사용자의 잔액과 기타 정보를 저장합니다. 트랜잭션 해시를 기반으로 엔티티 ID를 생성하면 사용자는 처음에 생성 한 트랜잭션을 검색하여 다시 생성 할 수 있지만 직관적이지 않습니다. 더 나은 대안은 사용자의 이더 리움 주소를 기반으로 ID를 만들고 필요한 경우이를 도메인과 관련된 다른 것과 결합하는 것입니다. 이렇게하면 동일한 사용자의 다른 계정에서 특정 사용자 계정을 고유하게 식별 할 수 있습니다.

요약하면 도메인 별 데이터가없는 일반 고유 ID는 지속적으로 업데이트되지 않는 항목에 유용 할 수 있습니다. 이는 기본 엔터티의 파생 배열에서 사용되는 도메인 특정 이벤트에 대한 메타 데이터를 저장하기 위해 생성 된 엔터티에 이상적입니다. 예를 들어, 일반 고유 ID는 전송, 민트, 소각 및 스왑에 더 적합합니다.

반면 도메인 별 ID는 주요 엔티티 및 자주 업데이트되는 기타 엔티티에 이상적입니다. 이더 리움 주소와 다른 도메인 특정 ID의 조합을 사용하고있을 가능성이 높습니다. 대부분의 경우 스마트 계약은 고유 ID를 생성하고 이벤트에 기록합니다. 그렇지 않은 경우 스마트 계약을 연구하고 엔티티를 고유하게 만드는 요소를 식별하고 해당 데이터를 사용하여 ID를 생성해야합니다.

부담으로 toHex()toHexString() 메서드 (일반적으로 주소 또는 해시에서 ID를 생성하는 데 사용됨)는 소문자 문자열을 반환합니다. 즉, 항목에 대한 하위 그래프를 쿼리 할 때 쿼리에서 대소 문자를 구분하므로 제공된 ID 문자열은 소문자 여야합니다.

서브 그래프 개발에 대한 자세한 내용은 The Graph의 공식 문서 . 추가 세부 정보는 프로젝트의 GitHub 저장소 에서도 확인할 수 있습니다. The Graph는 또한 발생하는 질문에 도움을주고 답변 할 준비가 된 활발하고 성장하는 커뮤니티를 보유하고 있습니다. 자신의 하위 그래프를 개발하는 데 관심이있는 사람은 누구나 Graph의 Discord 서버 에 참여할 것을 권장합니다.

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다