SpaceBear
SpaceBear

Reputation: 844

CoreData and the most common word used/tagged

I have an entry field similar to the "tags" feature on this site: user enters bunch of words or phrases that are shown in their own bubbles. These words/phrases are associated with a journal entry (basically tagging the journal entry) and on the overview page I would like to show top 5 or 10 of these words/phrases.

My initial implementation is to store a string in each journal entry that basically concatenates all of these words/phrases. When I read the data, I split this string based on predefined separator. That works pretty well, but finding top 5/10 will be super bad if I have a lot of entries that contain decent amount of these words/phrases. What would be a better approach to this?

So, i have something like this:

@interface JournalEntry : NSManagedObject
{
     @property (nonatomic, retain) NSNumber * entryId;
     @property (nonatomic, retain) NSDate * dateCreated;
     @property (nonatomic, retain) TagsInfo *tagsInfo;
}

@interface TagsInfo : NSManagedObject
{
     @property (nonatomic, retain) JournalEntry * journalEntry;
     @property (nonatomic, retain) NSString * tagString;
}

I think in a normal database setup, I would create a table for tags, where I would store something like [journalEntryId, tagEntry]. There would be a bunch of these entries for each journal entry. Should this be similiar?

Upvotes: 0

Views: 48

Answers (1)

Tom Harrington
Tom Harrington

Reputation: 70946

That's what I'd do, create a new Tag entity that has as many-to-many relationship to JournalEntry. Migrate the existing TagInfo to Tag and update the relationships.

Tag would have the following, at a minimum:

  • To-many relationship to JournalEntry
  • String called tagString (or tagName or whatever).

JournalEntry would have a to-many relationship back to Tag. The tagString would be unique, since each Tag could relate to multiple journal entries.

You could then fetch the tags along with a count of how many times each was used like this:

NSExpression *tagCountExpression = [NSExpression expressionWithFormat:@"count(journalEntries)"];
NSExpressionDescription *tagCountExprDescription = [[NSExpressionDescription alloc] init];
tagCountExprDescription.name = @"count";
tagCountExprDescription.expression = tagCountExpression;
tagCountExprDescription.expressionResultType = NSInteger64AttributeType;

NSFetchRequest *tagFetch = [NSFetchRequest fetchRequestWithEntityName:@"Tag"];
[tagFetch setResultType:NSDictionaryResultType];
tagFetch.propertiesToFetch = @[ @"tagString", tagCountExprDescription ];
tagFetch.propertiesToGroupBy = @[ @"tagString" ];

That would give you an array of dictionaries. Each would contain a tagString and a count of how many related journal entries that tag has. You'd have to sort it yourself (can't use expressions as sort descriptors).

Upvotes: 1

Related Questions