pshah
pshah

Reputation: 2082

Fetch newest record in to-many relationship efficiently in Core Data

I have a to-many relationship between a Channel and Messages i.e. A channel can have multiple messages and a message belongs to exactly one channel. I wanted to efficiently fetch the last message along with the channel. Please note that a channel can potentially have a large number of messages. I could think of a few different options:

  1. Make messages an ordered relationship on Channel and fetch the last message (using messages.last in Swift) Potential problem: From my limited experience, there might be some casts involved since NSOrderedSet doesn't support generics like Set does. I also read that the combination of ordered relationships in Core Data, Xcode and Swift have some quirks in general, so not sure.
  2. Make messages an un-ordered relationship on Channel and fetch the last message using a fetch request on Message (sorted by timestamp desc) Potential problem: Need a fetch request every time last message is accessed and this might be a potential performance problem.
  3. Add an additional to-one relationship called lastMessage on Channel and always keep it updated. Then, prefetch the lastMessage relationship along with the Channels using a single fetch request. Potential problem: Additional code to ensure lastMessage stays in sync.

To extend this problem further, if I wanted to fetch the last n messages instead of the last message, what would be the suggested approach?

Thanks a lot!

Upvotes: 1

Views: 162

Answers (1)

Mundi
Mundi

Reputation: 80265

I think your option 2 is the most solid one. There are a few tricks you can employ to ensure efficient fetching, so I think you will not run into any performance problems.

Option 3 is also feasible and not much effort either. Just implement didSet when setting the channel. However, it is not as clean and would not help with your "n last messages" problem.

Fetching sorted by date is really efficient. The trick is to set the appropriate sort descriptor on the fetch request and then set the fetchLimit to n, or to 1 if you are looking for the last message.

Make sure you check for "not found" or "found less than n" error conditions and handle them appropriately.

Upvotes: 2

Related Questions