Realm 객체 모델 정의 - Node.js SDK
이 페이지의 내용
Realm 객체 유형 정의
Realm 객체 유형 을 정의하려면 해당 유형의 name
및 properties
를 지정하는 스키마 객체 를 만듭니다. 유형 이름은 영역 의 객체 유형 간에 고유해야 합니다. 특정 속성을 정의하는 방법에 대한 자세한 내용은 객체 속성 정의를 참조하세요.
이 페이지에 있는 대부분의 예시처럼 JavaScript 클래스로 스키마를 정의할 수도 있지만, JavaScript 객체로 정의할 수도 있습니다.
const Car = { name: "Car", properties: { _id: "objectId", make: "string", model: "string", miles: "int?", }, };
자바스크립트 클래스로 Realm 객체 유형 정의
JavaScript 클래스로 Realm 객체 유형을 정의할 수 있습니다. 클래스를 객체 유형으로 사용하려면 정적 속성 schema
에 객체 스키마를 정의하세요.
class Car extends Realm.Object { static schema = { name: "Car", properties: { _id: { type: "objectId", default: () => new Realm.BSON.ObjectId() }, make: "string", model: "string", miles: "int?", }, primaryKey: "_id", }; }
참고
클래스 이름은 최대 57자의 UTF-8 문자로 제한됩니다.
영역을 열 때 클래스 자체를 Realm.Configuration 객체의 스키마 속성에 전달합니다. 그러면 정상적으로 데이터를 읽고 쓸 수 있습니다.
const realm = await Realm.open({ path: "myrealm", schema: [Car], }); let car1; realm.write(() => { car1 = realm.create(Car, { make: "Nissan", model: "Sentra", miles: 1000, }); });
지원되는 속성 유형
Realm 객체의 모든 속성에는 강력하게 정의된 데이터 유형이 있습니다. 속성 유형은 기본 데이터 유형이거나 동일한 영역에 정의된 객체 유형일 수 있습니다. 또한 유형은 속성에 단일 값이 포함되어 있는지 또는 값 목록이 포함되어 있는지 여부를 지정합니다.
Realm에서 지원하는 기본 데이터 유형은 다음과 같습니다:
bool
부울 값의 경우int
및double
은(는) JavaScriptnumber
값에 매핑됩니다Decimal128
고정밀 숫자의 경우string
date
,날짜 에 매핑됩니다.data
, 이는 ArrayBuffer 에 매핑됩니다.objectId
ObjectId에 매핑됩니다.
필드에 기본 값 유형 목록이 포함되도록 지정하려면 유형 이름에 []
을(를) 추가하세요.
객체 속성 정의
객체 유형의 속성을 정의하려면 properties
필드 아래에 속성의 이름과 데이터 유형을 나타내는 키-값 쌍을 만듭니다.
다음 스키마는 _id
make
, model
및 miles
속성이 있는 Car
유형을 정의합니다.
class Car extends Realm.Object { static schema = { name: "Car", properties: { _id: { type: "objectId", default: () => new Realm.BSON.ObjectId() }, make: "string", model: "string", miles: "int?", }, primaryKey: "_id", }; }
선택적 속성 지정
속성을 선택 사항으로 표시하려면 해당 유형에 물음표 ?
를 추가합니다.
다음 Car
스키마는 int
유형의 선택적 miles
속성을 정의합니다.
class Car extends Realm.Object { static schema = { name: "Car", properties: { _id: { type: "objectId", default: () => new Realm.BSON.ObjectId() }, make: "string", model: "string", miles: "int?", }, primaryKey: "_id", }; }
프라이머리 키 설정
속성을 객체 유형의 프라이머리 키로 지정하려면 스키마의 primaryKey
필드를 속성 이름으로 설정하세요.
참고
기본 키 는 객체를 고유하게 식별하는 속성입니다. Realm은 기본 키 속성을 자동으로 인덱싱 하므로 기본 키를 기반으로 객체를 효율적으로 읽고 수정할 수 있습니다.
객체 유형에 프라이머리 키가 있는 경우 해당 유형의 모든 객체에는 영역에 있는 동일한 유형의 객체와 비교했을 때 고유한 값을 갖는 프라이머리 키 속성이 포함되어야 합니다. 객체 유형에는 프라이머리 키가 하나만 있을 수 있습니다. 해당 유형의 객체를 영역에 추가한 후에는 해당 객체 유형의 프라이머리 키 속성을 변경할 수 없으며 객체의 프라이머리 키 값을 수정할 수 없습니다.
다음 Car
객체 스키마는 _id
속성을 기본 키로 지정합니다.
class Car extends Realm.Object { static schema = { name: "Car", properties: { _id: { type: "objectId", default: () => new Realm.BSON.ObjectId() }, make: "string", model: "string", miles: "int?", }, primaryKey: "_id", }; }
속성 인덱싱
Realm은 문자열, 정수, 부울, Date
, UUID
및 ObjectId
속성에 대한 인덱싱을 지원합니다. 주어진 속성에 대한 인덱스를 정의하려면 indexed
을(를) true
(으)로 설정합니다.
참고
인덱스를 사용하면 쓰기 시간이 약간 느려지고 스토리지 및 메모리 오버헤드가 늘어나는 대신 특정 읽기 작업의 속도가 크게 향상됩니다. Realm은 인덱스를 디스크에 저장하므로 영역 파일이 더 커집니다. 각 인덱스 항목은 최소 12바이트입니다. 인덱스 항목의 순서는 효율적인 동등성 매치 및 범위 기반 쿼리 작업을 지원합니다.
특정 상황에 대한 읽기 성능을 최적화하는 경우에만 인덱스를 추가하는 것이 가장 좋습니다.
다음 Car
객체 스키마는 _id
속성에 대한 인덱스를 정의합니다.
class Car extends Realm.Object { static schema = { name: "Car", properties: { _id: { type: "objectId", indexed: true }, make: "string", model_name: { type: "string", mapTo: "modelName" }, miles: { type: "int", default: 0 }, }, primaryKey: "_id", }; }
Full Text Search 인덱스 설정
Realm은 표준 인덱스 외에도 문자열 속성에 대한 FTS(Full-Text Search) 인덱스도 지원합니다. 표준 인덱스 유무에 관계없이 문자열 필드를 쿼리할 수 있지만 FTS 인덱스를 사용하면 여러 단어와 구를 검색하고 나머지는 제외할 수 있습니다.
FTS 인덱스 쿼리에 대한 자세한 내용은 Full Text Search를 참조하세요.
FTS 인덱스를 만들려면 인덱싱된 유형을 'full-text'
로 설정합니다. 이를 통해 속성에 대한 전체 텍스트 쿼리가 가능합니다. 다음 예제에서는 name
속성의 인덱싱된 유형을 'full-text'
으)로 설정합니다.
class Book extends Realm.Object<Book> { name!: string; price?: number; static schema: ObjectSchema = { name: "Book", properties: { name: { type: "string", indexed: "full-text" }, price: "int?", }, }; }
기본 속성 값 정의
기본값을 정의하려면 속성 값을 type
필드와 default
필드가 있는 객체로 설정하세요.
다음 Car
객체 스키마는 miles
속성에 대해 기본값 0
을 지정합니다.
class Car extends Realm.Object { static schema = { name: "Car", properties: { _id: { type: "objectId", indexed: true }, make: "string", model_name: { type: "string", mapTo: "modelName" }, miles: { type: "int", default: 0 }, }, primaryKey: "_id", }; }
속성 또는 클래스를 다른 이름에 매핑
기본적으로 Realm은 모델 클래스에 정의된 이름을 사용하여 내부적으로 클래스와 필드를 나타냅니다. 경우에 따라 이 동작을 변경하고 싶을 수도 있습니다. 예시:
명명 규칙이 서로 다른 플랫폼에서 더 쉽게 작업할 수 있습니다. 예를 들면 Device Sync 스키마 속성 이름은 스네이크 표기법을 사용하고, 프로젝트는 카멜 표기법을 사용하는 경우입니다.
마이그레이션을 강제하지 않고 클래스 또는 필드 이름을 변경합니다.
서로 다른 패키지에서 동일한 이름을 가진 여러 모델 클래스를 지원합니다.
클래스 이름이 Realm에서 지정한 57자 제한보다 긴 경우.
코드의 클래스 또는 속성 이름을 다른 이름으로 매핑하여 영역에 저장할 수 있습니다. 동기화된 영역에 쓰는 경우 Sync 스키마는 영구 클래스 또는 속성 이름을 사용하여 저장된 값을 확인합니다.
참고로 마이그레이션할 때는 영구 클래스 또는 속성 이름을 사용해야 하며 보고된 모든 스키마 오류도 영구 이름을 사용합니다.
영역에 저장된 것과 다른 클래스 이름을 코드에서 사용하려면 다음을 수행하세요.
Realm 객체 스키마의
name
속성을 객체를 저장할 때 사용할 이름으로 설정합니다.영역을 열때 영역 구성의
schema
속성에있는 클래스 이름을 사용합니다.CRUD 작업을 수행하거나 Flexible Sync 구독을 정의할 때 매핑된 이름을 사용하세요.
다음 예시에서 Realm은 Task
클래스로 만든 객체를 Todo_Item
(으)로 저장합니다.
class Task extends Realm.Object { static schema = { // Set the schema's `name` property to the name you want to store. // Here, we store items as `Todo_Item` instead of the class's `Task` name. name: "Todo_Item", properties: { _id: "int", name: "string", owner_id: "string?", }, primaryKey: "_id", }; } const config = { // Use the class name in the Configuration's `schema` property when // opening the realm. schema: [Task], sync: { user: anonymousUser, flexible: true, initialSubscriptions: { update: (subs, realm) => { subs.add( realm // Use the mapped name in Flexible Sync subscriptions. .objects(`Todo_Item`) .filtered(`owner_id == "${anonymousUser.id}"`) ); }, }, }, }; const realm = await Realm.open(config); realm.write(() => { // Use the mapped name when performing CRUD operations. realm.create(`Todo_Item`, { _id: 12342245, owner_id: anonymousUser.id, name: "Test the Todo_Item object name", }); }); // Use the mapped name when performing CRUD operations. const assignedTasks = realm.objects(`Todo_Item`);
class Task extends Realm.Object<Task> { _id!: number; name!: string; owner_id?: string; static schema: ObjectSchema = { // Set the schema's `name` property to the name you want to store. // Here, we store items as `Todo_Item` instead of the class's `Task` name. name: "Todo_Item", properties: { _id: "int", name: "string", owner_id: "string?", }, primaryKey: "_id", }; } const config: Realm.Configuration = { // Use the class name in the Configuration's `schema` property when // opening the realm. schema: [Task], sync: { user: anonymousUser, flexible: true, initialSubscriptions: { update: (subs, realm) => { subs.add( realm // Use the mapped name in Flexible Sync subscriptions. .objects(`Todo_Item`) .filtered(`owner_id == "${anonymousUser.id}"`) ); }, }, }, }; const realm = await Realm.open(config); realm.write(() => { // Use the mapped name when performing CRUD operations. realm.create(`Todo_Item`, { _id: 12342245, owner_id: anonymousUser.id, name: "Test the Todo_Item object name", }); }); // Use the mapped name when performing CRUD operations. const assignedTasks = realm.objects(`Todo_Item`);
영역 에 저장된 것과 다른 속성 이름을 코드에서 사용하려면 코드에 표시되는 속성 이름으로 mapTo
를 설정하다 합니다.
다음 Car
객체 스키마 에서 Realm 은 자동차의 모델 이름을 스네이크 케이스 model_name
속성 과 함께 저장합니다. 스키마 는 클라이언트 코드에 사용되는 객체의 속성 을 modelName
에 매핑합니다.
class Car extends Realm.Object { static schema = { name: "Car", properties: { _id: { type: "objectId", indexed: true }, make: "string", model_name: { type: "string", mapTo: "modelName" }, miles: { type: "int", default: 0 }, }, primaryKey: "_id", }; }
관계 속성 정의
대일 관계 속성 정의
to-one 관계는 속성 한 개를 다른 객체 유형의 단일 인스턴스에 매핑합니다. 예를 들어 최대 한 대의 자동차를 보유한 제조업체를 to-one 관계로 모델링할 수 있습니다.
to-one 관계 속성을 정의하려면 관련 객체 유형 이름을 속성 유형으로 지정합니다.
중요
대일 관계는 선택 사항이어야 합니다.
객체 모델에서 대일 관계를 선언할 때는 선택적 속성이어야 합니다. 대일 관계를 필수로 만들려고 하면 Realm은 런타임에 예외를 발생시킵니다.
다음 Manufacturer
객체 스키마는 제조업체가 단일 Car
을(를) 만들 수도 있고 만들지 않을 수도 있음을 지정합니다. Car
을(를) 만들면 Realm은 car
속성을 통해 이에 연결합니다.
class Manufacturer extends Realm.Object { static schema = { name: "Manufacturer", properties: { _id: "objectId", // A manufacturer that may have one car car: "Car?", }, }; } class Car extends Realm.Object { static schema = { name: "Car", properties: { _id: "objectId", make: "string", model: "string", miles: "int?", }, }; }
대다 관계 속성 정의
To-many 관계는 한 속성을 다른 객체 유형의 0개 이상 인스턴스에 매핑합니다. 예를 들어, to-many 관계로 자동차 수에 관계없이 제조업체를 모델링할 수 있습니다.
to-many 관계 속성을 정의하려면 관련 객체 유형 이름을 목록으로 지정합니다.
애플리케이션은 다음 객체 스키마를 사용하여 Manufacturer
가 여러 Car
객체를 만듦을 나타낼 수 있으며, 이때 cars
속성에 자동차 객체를 포함합니다.
class Manufacturer extends Realm.Object { static schema = { name: "Manufacturer", properties: { _id: "objectId", // A manufacturer that may have many cars cars: "Car[]", }, }; } class Car extends Realm.Object { static schema = { name: "Car", properties: { _id: "objectId", make: "string", model: "string", miles: "int?", }, }; }
역관계 속성 정의
역관계 속성은 자동 역링크 관계입니다. Realm은 해당 to-many 목록에서 객체가 추가되거나 제거될 때마다 암시적 관계를 자동으로 업데이트합니다. 역관계 속성의 값은 수동으로 설정할 수 없습니다.
역관계 속성을 정의하려면 속성 유형을 linkingObjects
로 설정하고 반전할 관계를 정의하는 객체 유형과 속성 이름을 지정합니다.
애플리케이션은 다음 객체 스키마를 사용하여 Manufacturer
이(가) 많은 Car
객체를 만들 수 있으며 각 Car
이(가) 어느 Manufacturer
에서 생산되는지 자동으로 추적해야 함을 나타낼 수 있습니다.
Manufacturer
객체의cars
속성은 to-many 관계로 정의됩니다Car
객체와 함께 특정 제조업체의 모든 자동차를 포함합니다.
Car
객체의assignee
속성은 이 관계를 반전시킵니다.cars
속성에 자동차가 포함된 모든Manufacturer
객체를 다시 참조하도록 자동으로 업데이트됩니다.
class Manufacturer extends Realm.Object { static schema = { name: "Manufacturer", properties: { _id: "objectId", // A manufacturer that may have many cars cars: "Car[]", }, }; } class Car extends Realm.Object { static schema = { name: "Car", properties: { _id: "objectId", make: "string", model: "string", miles: "int?", // Backlink to the manufacturer. This is automatically updated whenever // this car is added to or removed from a manufacturer's cars list. assignee: { type: "linkingObjects", objectType: "Manufacturer", property: "cars", }, }, }; }
내장된 객체 속성 정의
내장된 객체(중첩된 Realm 객체)가 포함된 Realm 객체 모델을 정의하려면 embedded
을(를) true
(으)로 설정합니다.
내장된 객체는 하나의 특정 상위 객체 내에 중첩된 데이터로 존재합니다. 상위 객체의 수명 주기를 상속받으며 독립적인 Realm 객체로 존재할 수 없습니다. Realm은 상위 객체가 삭제되거나 새 내장된 객체 인스턴스로 덮어쓰면 내장된 객체를 자동으로 삭제합니다. 내장된 객체는 프라이머리 키를 가질 수 없습니다.
관계와 같은 방식으로 상위 객체 유형에서 내장된 객체 유형을 참조할 수 있습니다.
다음 예시에는 Manufacturer
및 Car
라는 두 개의 상위 스키마가 필요합니다. 애플리케이션에 포함된 하위 스키마 Warranty
가 필요합니다. Manufacturer
객체는 Warranty
객체 목록을 포함할 수 있는 반면 Car
객체는 단일 Warranty
객체만 포함할 수 있습니다.
class Manufacturer extends Realm.Object { static schema = { name: "Manufacturer", properties: { _id: "objectId", name: "string", // Embed an array of objects warranties: { type: "list", objectType: "Warranty" }, }, }; } class Car extends Realm.Object { static schema = { name: "Car", properties: { _id: "objectId", make: "string", model: "string", miles: "int?", // Embed one object warranty: "Warranty", }, }; } class Warranty extends Realm.Object { static schema = { name: "Warranty", embedded: true, properties: { name: "string", termLength: "int", cost: "int", }, }; }
비대칭 객체 정의
버전 12.2.1에서 변경되었습니다.
Flexible Sync를 사용 중이고 기기에서 Atlas 데이터베이스로 컬렉션을 단방향으로 동기화해야 하는 경우 객체 스키마에서 asymmetric
속성을 설정할 수 있습니다.
class WeatherSensor extends Realm.Object { static schema = { name: "WeatherSensor", // Sync WeatherSensor objects one way from your device // to your Atlas database. asymmetric: true, primaryKey: "_id", properties: { _id: "objectId", deviceId: "string", temperatureInFahrenheit: "int", barometricPressureInHg: "float", windSpeedInMph: "float", }, }; }
class WeatherSensor extends Realm.Object<WeatherSensor> { _id!: Realm.BSON.ObjectId; deviceId!: string; temperatureInFahrenheit!: number; barometricPressureInHg!: number; windSpeedInMph!: number; static schema: ObjectSchema = { name: "WeatherSensor", // sync WeatherSensor objects one way from your device // to your Atlas database. asymmetric: true, primaryKey: "_id", properties: { _id: "objectId", deviceId: "string", temperatureInFahrenheit: "int", barometricPressureInHg: "float", windSpeedInMph: "float", }, }; }
Node.js SDK 버전 12.2.0 이하에서는 비대칭 객체에서 Realm.Object
유형으로 연결할 수 없습니다. SDK 버전 12.2.1 이상에서는 비대칭 객체가 내장된 객체 외에 Realm.Object
유형에 링크할 수 있습니다.
참고
비대칭 객체 읽기 시도
비대칭 객체는 읽을 수 없습니다. 비대칭 객체를 쿼리하려고 하면 '오류: 비대칭 클래스는 쿼리할 수 없습니다'라는 오류가 발생합니다.
데이터 수집에 대해 자세히 알아보려면 데이터 수집을 통한 동기화 최적화를 참조하세요.
비정형 데이터 정의
버전 12.9.0에 추가 되었습니다.
Node.js SDK 버전 12.9.0 부터 mixed
속성 내에 혼합 데이터 컬렉션을 저장 수 있습니다. 이 기능 을 사용하면 엄격한 데이터 모델 을 정의하지 않고도 JSON 또는 MongoDB 문서와 같은 복잡한 데이터 구조를 모델링할 수 있습니다.
구조화되지 않은 데이터 는 예상 스키마 를 쉽게 준수하지 않는 데이터로, 개별 데이터 클래스를 모델링하기가 어렵거나 비실용적입니다. 예를 예시 앱 에 매우 가변적인 데이터나 런타임에 구조를 알 수 없는 동적 데이터가 있을 수 있습니다.
컬렉션을 혼합 속성 에 저장하면 Device Sync 사용 시 성능 동기화를 포함하여 기능을 희생하지 않고도 유연성을 확보할 수 있습니다. 혼합되지 않은 컬렉션 과 동일한 방식으로 작업할 수 있습니다.
혼합 컬렉션을 최대 100 수준까지 중첩할 수 있습니다.
혼합 컬렉션의 변경React 을 쿼리 하고 이에 대응할 수 있습니다.
개별 혼합 컬렉션 요소를 찾고 업데이트 할 수 있습니다.
그러나 혼합된 컬렉션에 데이터를 저장하는 것은 구조화된 스키마 를 사용하거나 JSON blob을 단일 string 속성 으로 직렬화하는 것보다 성능이 떨어집니다.
앱 에서 구조화되지 않은 데이터를 모델링하려면 스키마 에서 적절한 속성을 혼합 유형으로 정의합니다. 그런 다음 이러한 mixed
속성을 혼합 요소의 목록 또는 사전 컬렉션 으로 설정하다 수 있습니다. mixed
은(는) 설정하다 이나 내장된 객체 를 나타낼 수 없습니다 .
팁
유형을 알 수 없지만 각 값에 고유 식별자가 있는 경우 혼합 데이터 유형의 맵을 사용합니다.
유형을 알 수 없지만 객체의 순서가 의미 있는 경우 혼합 데이터 유형 목록을 사용합니다.