谓词子查询通过匹配标记返回项目

时间:2014-06-08 06:13:25

标签: core-data tags many-to-many subquery predicate

我在两个实体之间有多对多的关系;物品和标签。我试图创建一个谓词来获取selectedItem并根据它们有多少相似的标签返回项目的排名。到目前为止,我已经尝试过:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SUBQUERY(itemToTag, $item, $item in %@).@count > 0", selectedItem.itemToTag];

任何其他失败的迭代。它目前只返回列表中的selectedItem。我在Subquery上找不到什么。那里有一位古茹可以帮助我改进这个吗?

提前感谢您的帮助!

编辑9月6日

好消息是Dan的代码我可以用项目填充tableview!不幸的是,排名是0。

解决方案 我最初尝试按ID而不是名称搜索标签。请注意“排名记录描述”标记中的两个谓词选项:'我没有标签的唯一标识符,并使用两个选项中的第二个。谢谢Dan!

1 个答案:

答案 0 :(得分:0)

谓词只是一个开头。

首先看看THIS非常类似的问题。

假设您的模型中有ItemTag个实体,这些实体与多对多关系相关:
Item.tags<< - >> Tag.items

答案:

- (NSExpressionDescription*) rankingExpressionDescriptionForTags:(NSSet*)tags
{
    NSPredicate* p = [NSPredicate predicateWithFormat:@"SUBQUERY(tags,$t,$t IN %@).@count > 0",tags];
    //if your tags are not unique (meaning you only like to match the names of tags)
    //change the predicate to:
    //p = [NSPredicate predicateWithFormat:@"SUBQUERY(tags,$t,$t.tagName IN %@).@count > 0",[tags valueForKey:@"tagName"]];
    NSExpression* rankExpresion = [(NSComparisonPredicate*)p2 leftExpression];
    NSExpressionDescription* rankExpDesc = [[NSExpressionDescription alloc] init];
    rankExpDesc.name = @"ranking";
    rankExpDesc.expression = rankExpresion;
    rankExpDesc.expressionResultType = NSInteger64AttributeType;
    return rankExpDesc;
}

- (NSExpressionDescription*) objectIDExpressionDescription
{
    NSExpressionDescription* expDesc = [[NSExpressionDescription alloc] init];
    expDesc.name = @"objectID";
    expDesc.expressionResultType = NSObjectIDAttributeType;
    expDesc.expression = [NSExpression expressionForEvaluatedObject];
    return expDesc;
}

- (NSFetchRequest*) rankingRequestForItem:(NSManagedObject*)item
{
    NSFetchRequest* r = [NSFetchRequest fetchRequestWithEntityName:@"Item"];
    NSPredicate* p = [NSPredicate predicateWithFormat:@"SELF != %@",item.objectID];
    r.resultType = NSDictionaryResultType;
    r.propertiesToFetch = @[[self objectIDExpressionDescription],
                            [self rankingExpressionDescriptionForTags:[item mutableSetValueForKey:@"tags"]]];
    r.predicate = p;
    return r;
}

注意:

  1. 生成的数组包含词典
  2. (AFAIK)如果您想按排名排序,则必须在获取后对结果数组进行内存排序
  3. 无法使用提取的结果控制器来跟踪这些对象的更改
  4. 您可以使用FRC显示这些项目