문서 메뉴
문서 홈
/ /
Atlas Device SDK
/ /

Realm 객체 모델 정의 - Node.js SDK

이 페이지의 내용

  • Realm 객체 유형 정의
  • 자바스크립트 클래스로 Realm 객체 유형 정의
  • 지원되는 속성 유형
  • 개체 속성 정의
  • 선택적 속성 지정
  • 프라이머리 키 설정
  • 속성 인덱싱
  • Full Text Search 인덱스 설정
  • 기본 속성 값 정의
  • 속성 또는 클래스를 다른 이름에 매핑
  • 관계 속성 정의
  • 대일 관계 속성 정의
  • 대다 관계 속성 정의
  • 역관계 속성 정의
  • 내장된 객체 속성 정의
  • 비대칭 객체 정의
  • 비정형 데이터 정의

Realm 객체 유형을 정의하려면 해당 유형의 nameproperties 를 지정하는 스키마 객체를 만듭니다. 유형 이름은 영역의 객체 유형 간에 고유해야 합니다. 특정 속성을 정의하는 방법에 대한 자세한 내용은 객체 속성 정의를 참조하세요.

이 페이지에 있는 대부분의 예제처럼 JavaScript 클래스로 스키마를 정의할 수도 있지만, JavaScript 객체로 정의할 수도 있습니다.

const Car = {
name: "Car",
properties: {
_id: "objectId",
make: "string",
model: "string",
miles: "int?",
},
};

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 부울 값의 경우

  • intdouble은(는) JavaScript number 값에 매핑됩니다

  • Decimal128 고정밀 숫자의 경우

  • string

  • dateDate에 매핑됩니다.

  • data, 이는 ArrayBuffer 에 매핑됩니다.

  • objectIdObjectId에 매핑됩니다.

필드에 기본 값 유형 목록이 포함되도록 지정하려면 유형 이름에 []을(를) 추가하세요.

개체 유형의 속성을 정의하려면 properties 필드 아래에 속성의 이름과 데이터 유형을 나타내는 키-값 쌍을 만듭니다.

다음 스키마는 _id make, modelmiles 속성이 있는 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은 기본 키 속성을 자동으로 인덱싱 하므로 기본 키를 기반으로 객체를 효율적으로 읽고 수정할 수 있습니다.

객체 유형에 프라이머리 키가 있는 경우 해당 유형의 모든 객체에는 Realm에 있는 동일한 유형의 객체와 비교했을 때 고유한 값을 갖는 프라이머리 키 속성이 포함되어야 합니다. 객체 유형에는 프라이머리 키가 하나만 있을 수 있습니다. 해당 유형의 객체를 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, UUIDObjectId 속성에 대한 인덱싱을 지원합니다. 주어진 속성에 대한 인덱스를 정의하려면 indexed을(를) true(으)로 설정합니다.

참고

인덱스를 사용하면 쓰기 시간이 약간 느려지고 스토리지 및 메모리 오버헤드가 늘어나는 대신 특정 읽기 작업의 속도가 크게 향상됩니다. Realm은 인덱스를 디스크에 저장하므로 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",
};
}

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자 제한보다 긴 경우.

코드의 클래스 또는 속성 이름을 다른 이름으로 매핑하여 Realm에 저장할 수 있습니다. 동기화된 Realm에 쓰는 경우 Sync 스키마는 영구 클래스 또는 속성 이름을 사용하여 저장된 값을 확인합니다.

참고로 마이그레이션할 때는 영구 클래스 또는 속성 이름을 사용해야 하며 보고된 모든 스키마 오류도 영구 이름을 사용합니다.

영역에 저장된 것과 다른 클래스 이름을 코드에서 사용하려면 다음을 수행하세요.

  1. Realm 객체 스키마name 속성을 객체를 저장할 때 사용할 이름으로 설정합니다.

  2. 영역을 열때 Realm 구성의 schema 속성에있는 클래스 이름을 사용합니다.

  3. 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",
};
}

다음도 참조하세요.

또한 App Services 앱에서 관계를 정의할 수도 있습니다.

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은 상위 객체가 삭제되거나 새 포함된 객체 인스턴스로 덮어쓰면 포함된 객체를 자동으로 삭제합니다. 포함된 객체는 프라이머리 키를 가질 수 없습니다.

관계와 같은 방식으로 상위 객체 유형에서 내장된 객체 유형을 참조할 수 있습니다.

다음 예제에는 ManufacturerCar라는 두 개의 상위 스키마가 필요합니다. 애플리케이션에 포함된 하위 스키마 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 사용 시 성능 동기화를 포함하여 기능을 저하시키지 않으면서도 유연성을 확보할 수 있습니다. 그리고 혼합되지 않은 컬렉션과 동일한 방식으로 작업할 수 있습니다.

그러나 혼합된 컬렉션에 데이터를 저장하는 것은 구조화된 스키마를 사용하거나 JSON blob을 단일 문자열 속성으로 직렬화하는 것보다 성능이 떨어집니다.

앱에서 구조화되지 않은 데이터를 모델링하려면 스키마에서 적절한 속성을 혼합 유형으로 정의합니다. 그런 다음 이러한 mixed 속성을 혼합 요소의 목록 또는 사전 컬렉션으로 설정할 수 있습니다. mixed 는 세트나 포함된 객체를 나타낼 수 없습니다 .

  • 유형을 알 수 없지만 각 값에 고유 식별자가 있는 경우 혼합 데이터 유형의 맵을 사용합니다.

  • 유형을 알 수 없지만 객체의 순서가 의미 있는 경우 혼합 데이터 유형 목록을 사용합니다.

돌아가기

모델 데이터

다음

관계 & 포함된 객체