1

I have been struggling with this challenge for about a week now and have not yet been able to find proper solution. My challenge is this:

I have a JSON model which contains a property list of arbitrary key/value pairs. What I mean is, the key/value pairs are unknown at compilation time. It is quite easy to model and store JSON in Core Data as long the model is defined before hand, however if you do not know the name of the keys and the type of the values, things become difficult fast. In my case this is the reality I am facing.

My model looks something like this:

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

Now, ideally, I need to be able to perform searches on these arbitrary key/value pairs directly in the store. I am able to do that following a similar approach to the one described in Arbitrary Attributes in Core Data and How can I use NSPredicate to filter on core data relationships? using sub queries with NSPredicates.

Following this approach I have something like an "Object" entity with a to-many relationship with a "Property" entity:

Object <--->> Property

A property has two attributes "key" and "value":

Property
    key : someKey
    value : someValue

This effectively allows me to model and persist arbitrary keys inside the property list of my JSON object in Core Data. And using a sub query like the following I can fetch based on these key/value pairs (written in browser, no compiler etc.):

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

Up until now everything is fine and dandy, as long as the type of "key" and "value" is known. The key will always be a string and if I limit myself to value always being a string as well I am good to go and that's the end of it. I have my Object/Property relationship and I can associate arbitrary keys with string values and search based on these in storage.

However, I would like the solution to be a bit more flexible, I would like to support String, Int, Bool, Date, which are usually found in JSON and also exist as types in Core Data, but I have not been able to find a good approach for this. Maybe there's something I am just missing?

My first approach was to have a Property abstract entity with a relationship to Object and being parent to a StringProperty, NumberProperty etc. The key would be defined in Property and the value in either of the children, meaning I could type the value string in StringProperty and Integer16 in NumberProperty etc, however this will not work, since Property does not define a value, and thus I am not able to perform a search on the general level of the Property/Object relationship.

I am now considering getting rid of the Parent/Child structure and just create a StringProperty and a NumberProperty and then let each have a relationship with Object, which means Object would have a to-many relationship with StringProperty and a to-many relationship with NumberProperty. This is not super elegant, but I would probably be able to hide this implementation in the interface somewhere.

I really don't like this solution, but this is the route I am thinking of going now. Other things I have conidered: Transformable attributes, but these will not be searchable in storage. Also: Drop search in storage all together, just store the JSON string for the property list and turn it into an NSDictionary on request, but I consider this a last resort.

Any suggestions, there may be an approach that I just cant see for trees?

Community
  • 1
  • 1
Darumar
  • 71
  • 9

0 Answers0