混合 - React Native SDK
在版本中进行了更改realm@12.9.0
:混合属性可以包含混合数据的列表或字典。
realm@10.5.0
版本中的新增功能。
混合数据类型是一种域属性类型,可以保存除嵌入式对象或设立之外的任何有效Realm数据类型。 您可以创建类型为mixed
的集合(列表、集和字典)。 使用混合数据类型的属性还可以保存 null 值。
混合类型是可索引的,但不能将其用作主键。
使用“混合”类型的属性可以包含 null 值,并且不能定义为可选。 Realm 混合类型中 JavaScript Number
类型的所有实例都映射到 Realm double
类型。
Realm 对象模型
要将对象模型的属性设置为“混合”,请将该属性的类型设置为mixed
。
class Cat extends Realm.Object { static schema = { name: 'Cat', properties: { name: 'string', birthDate: 'mixed', }, }; }
class Cat extends Realm.Object<Cat> { name!: string; birthDate?: Realm.Mixed; static schema: ObjectSchema = { name: 'Cat', properties: { name: 'string', birthDate: 'mixed', }, }; }
混合集合
在JavaScript SDK v12.9.0 及更高版本中,混合数据类型可以保存混合元素的集合(列表或字典,但不是设立)。 您可以使用混合集合对非结构化或可变数据进行建模。 有关更多信息,请参阅定义非结构化数据。
您最多可以嵌套100级混合集合。
您可以查询混合集合属性并注册变更监听器,就像查询普通集合一样。
您可以查找并更新单个混合集合元素
不能在混合集合中存储集合或嵌入式对象。
要使用混合集合,请在数据模型中定义混合类型属性。 然后,创建列表或字典集合。
创建具有混合值的对象
创建具有混合值的对象,方法是使用 new 写事务(write transaction)中 的操作符。
例子
在以下CreateCatsInput
示例中,我们为birthDate
字段创建多个具有混合类型的Cat
Realm 对象。
CreateCatsInput
组件将执行以下操作:
调用
useRealm()
钩子以访问打开的 Realm 实例。使用 React 的 useEffect
useEffect
钩子,使用 和空依赖大量仅调用匿名函数一次。在匿名函数中,我们使用
new
操作符创建四个不同的Cat
对象,以便在写事务(write transaction)中创建新的域对象。 每个Cat
对象对birthDate
属性使用不同的数据类型。使用
useQuery()
钩子检索所有Cat
对象。地图 通过猫来呈现
Text
组件列表,其中显示每只猫的name
和birthDate
。
1 const CreateCatsInput = () => { 2 const realm = useRealm(); 3 4 useEffect(() => { 5 // Add data to the Realm when the component mounts 6 realm.write(() => { 7 // create a Cat with a birthDate value of type string 8 realm.create('Cat', { 9 name: 'Euler', 10 birthDate: 'December 25th, 2017', 11 }); 12 13 // create a Cat with a birthDate value of type date 14 realm.create('Cat', { 15 name: 'Blaise', 16 birthDate: new Date('August 17, 2020'), 17 }); 18 19 // create a Cat with a birthDate value of type int 20 realm.create('Cat', {name: 'Euclid', birthDate: 10152021}); 21 22 // create a Cat with a birthDate value of type null 23 realm.create('Cat', {name: 'Pythagoras', birthDate: null}); 24 }); 25 }, []); 26 27 // retrieve all cats 28 const cats = useQuery(Cat); 29 30 return ( 31 <> 32 {cats.map(cat => ( 33 <View> 34 <Text>{cat.name}</Text> 35 <Text>{String(cat.birthDate)}</Text> 36 </View> 37 ))} 38 </> 39 ); 40 };
1 const CreateCatsInput = () => { 2 const realm = useRealm(); 3 4 useEffect(() => { 5 // Add data to the Realm when the component mounts 6 realm.write(() => { 7 // create a Cat with a birthDate value of type string 8 realm.create('Cat', { 9 name: 'Euler', 10 birthDate: 'December 25th, 2017', 11 }); 12 13 // create a Cat with a birthDate value of type date 14 realm.create('Cat', { 15 name: 'Blaise', 16 birthDate: new Date('August 17, 2020'), 17 }); 18 19 // create a Cat with a birthDate value of type int 20 realm.create('Cat', {name: 'Euclid', birthDate: 10152021}); 21 22 // create a Cat with a birthDate value of type null 23 realm.create('Cat', {name: 'Pythagoras', birthDate: null}); 24 }); 25 }, []); 26 27 // retrieve all cats 28 const cats = useQuery(Cat); 29 30 return ( 31 <> 32 {cats.map(cat => ( 33 <View> 34 <Text>{cat.name}</Text> 35 <Text>{String(cat.birthDate)}</Text> 36 </View> 37 ))} 38 </> 39 ); 40 };
查询具有混合值的对象
要查询具有混合值的对象,请运行Collection.filtered() 方法,并传入针对 non-Mixed 字段的过滤。 然后,您可以打印 Mixed属性的值或整个对象本身。
例子
在以下CatInfoCard
示例中,我们使用猫的名称查询Cat
对象。
CatInfoCard
组件将执行以下操作:
通过将
Cat
类传递给useQuery()
钩子来获取所有Cat
对象,然后使用filtered()
筛选结果以仅接收名称与作为属性传递的名称匹配的猫。 然后,我们获取第一只匹配的猫并将其存储为常量变量。使用点表示法检索“混合”属性
birthDate
。如果 Realm 找到了猫,则在呈现方法中显示猫的名称和出生日期。 如果没有与作为属性传递给组件的名称匹配的猫,我们会渲染“未找到猫”的文本。
1 const CatInfoCard = ({catName}) => { 2 // To query for the cat's birthDate, filter for their name to retrieve the realm object. 3 // Use dot notation to access the birthDate property. 4 const cat = useQuery( 5 Cat, 6 cats => { 7 return cats.filtered(`name = '${catName}'`); 8 }, 9 [catName], 10 )[0]; 11 const catBirthDate = cat.birthDate; 12 13 if (cat) { 14 return ( 15 <> 16 <Text>{catName}</Text> 17 <Text>{String(catBirthDate)}</Text> 18 </> 19 ); 20 } else { 21 return <Text>Cat not found</Text>; 22 } 23 };
1 type CatInfoCardProps = {catName: string}; 2 3 const CatInfoCard = ({catName}: CatInfoCardProps) => { 4 // To query for the cat's birthDate, filter for their name to retrieve the realm object. 5 // Use dot notation to access the birthDate property. 6 const cat = useQuery( 7 Cat, 8 cats => { 9 return cats.filtered(`name = '${catName}'`); 10 }, 11 [catName], 12 )[0]; 13 const catBirthDate = cat.birthDate; 14 15 if (cat) { 16 return ( 17 <> 18 <Text>{catName}</Text> 19 <Text>{String(catBirthDate)}</Text> 20 </> 21 ); 22 } else { 23 return <Text>Cat not found</Text>; 24 } 25 };
混合属性和类型检查
由于混合属性可以有多个类型,因此您不能依赖该属性的值是特定类型。
使用Object.getPropertyType()时, 您可以获得混合属性的根本的类型。 这允许您构建自己的类型检查。
// Use Type Predicates and Object.getPropertyType() to // create a runtime type check for Mixed properties. const isString = ( val: Mixed, name: string, object: Realm.Object, ): val is Realm.Types.String => { return object.getPropertyType(name) === 'string'; }; type CatInfoCardProps = {catName: string}; const CatInfoCard = ({catName}: CatInfoCardProps) => { const cat = useQuery( Cat, cats => { return cats.filtered(`name = '${catName}'`); }, [catName], )[0]; // Use the type check to handle your data. const catBirthDate = isString(cat.birthDate, 'birthDate', cat) ? cat.birthDate : cat.birthDate.toString(); if (cat) { return ( <> <Text>{catName}</Text> <Text>{catBirthDate}</Text> </> ); } else { return <Text>Cat not found</Text>; } };