【问题标题】:predicate subquery to return items by matching tags谓词子查询通过匹配标签返回项目
【发布时间】:2014-06-08 06:13:25
【问题描述】:

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

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

任何其他失败的迭代。它目前只返回列表中的 selectedItem。我在子查询上发现很少。有没有大师可以帮助我完善这个?

提前感谢您的帮助!

6 月 9 日编辑

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

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

【问题讨论】:

  • 它似乎与THIS 非常相似,但更精致一些。

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


【解决方案1】:

谓词只是开始。

先看看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 来显示这些项目

【讨论】:

  • 感谢您的回复。当我转到 tableview 时,应用程序关闭并返回“未解决的错误(null),(null)”。我还是个新手,可能会遗漏一些明显的东西。类似的报告问题可能指向 managedobjectcontext。这里有什么我错过的吗?
  • 确切的错误信息是什么?添加一个异常断点,看看是哪一行导致了异常。
  • 我已经在 viewdidload 中找到了它:NSError *error; if (![[self fetchedResultsController] performFetch:&error]) { // 更新以适当地处理错误。 NSLog(@"未解决的错误 %@, %@", error, [error userInfo]);退出(-1);
  • 我发现我从来没有输入过nsexpressiondescription。我已将其作为属性包含并合成它。我需要输入什么?
  • 您似乎还有另一个问题,您的fetchedResultsController 可能会返回nil。您需要将它包含在需要使用请求的地方。它不必是一个属性。
猜你喜欢
  • 1970-01-01
  • 2012-03-22
  • 1970-01-01
  • 2010-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多