1

我已经为这个挑战苦苦挣扎了大约一个星期,但还没有找到合适的解决方案。我的挑战是这样的:

我有一个 JSON 模型,其中包含任意键/值对的属性列表。我的意思是,键/值对在编译时是未知的。只要事先定义好模型,在 Core Data 中建模和存储 JSON 就很容易,但是如果您不知道键的名称和值的类型,事情很快就会变得困难。就我而言,这就是我所面临的现实。

我的模型看起来像这样:

{
    knownKey1:knownType1,
    knownKey2:knownType2,
    properties:{
        someKey1:someType1,
        someKey2:someType2,
    }
}

现在,理想情况下,我需要能够直接在商店中对这些任意键/值对执行搜索。我可以按照与核心数据中的任意属性如何使用 NSPredicate 过滤核心数据关系中描述的方法类似的方法来做到这一点。使用带有 NSPredicates 的子查询。

按照这种方法,我有一个类似于“对象”实体的东西,它与“属性”实体具有一对多关系:

Object <--->> Property

一个属性有两个属性“key”和“value”:

Property
    key : someKey
    value : someValue

这有效地允许我在 Core Data 中我的 JSON 对象的属性列表中建模和持久化任意键。并且使用像下面这样的子查询,我可以根据这些键/值对(在浏览器中编写,没有编译器等)获取:

NSPredicate *predicate = [NSPredicate predicateWithFormat: @"SUBQUERY($properties, $element, $element.key == %@ AND $element.value == %@) != 0", someKey, someValue];

到目前为止,只要知道“键”和“值”的类型,一切都很好。键将始终是一个字符串,如果我将自己的价值限制为始终是一个字符串,那么我很高兴,这就是它的结尾。我有我的对象/属性关系,我可以将任意键与字符串值相关联,并根据这些在存储中进行搜索。

但是,我希望解决方案更灵活一点,我想支持 String、Int、Bool、Date,它们通常在 JSON 中找到,并且在 Core Data 中也作为类型存在,但我一直没能找到一个很好的方法。也许我只是缺少一些东西?

我的第一种方法是拥有一个与 Object 有关系并作为 StringProperty、NumberProperty 等的父级的 Property 抽象实体。键将在 Property 中定义,而在任一子级中定义值,这意味着我可以在 StringProperty 中键入值字符串和 NumberProperty 等中的 Integer16,但是这不起作用,因为 Property 没有定义值,因此我无法在 Property/Object 关系的一般级别上执行搜索。

我现在正在考虑摆脱父/子结构,只创建一个 StringProperty 和一个 NumberProperty,然后让每个都与 Object 建立关系,这意味着 Object 将与 StringProperty 建立一对多关系,与 NumberProperty 建立一对多关系. 这不是很优雅,但我可能可以将这个实现隐藏在接口的某个地方。

我真的不喜欢这个解决方案,但这是我现在正在考虑的路线。我考虑过的其他事情:可转换的属性,但这些在存储中是不可搜索的。另外:将搜索放在一起存储,只需存储属性列表的 JSON 字符串并根据请求将其转换为 NSDictionary,但我认为这是最后的手段。

有什么建议,可能有一种我看不到树木的方法?

4

0 回答 0