谓词子查询通过匹配标记返回项目 [英] predicate subquery to return items by matching tags

查看:128
本文介绍了谓词子查询通过匹配标记返回项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个实体之间的多对多关系;项目和标签。我试图创建一个谓词,以获取selectedItem,并返回项目的排名,基于它们有多少相似的标签。到目前为止我试过:

I have a many-to-many relationship between two entities; Item and Tag. I'm trying to create a predicate to take the selectedItem and return a ranking of items based on how many similar tags they have. So far I've tried:

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

任何其他失败的迭代。它目前只返回列表中的selectedItem。我在Subquery上找不到。

Any other iterations that have failed. It currently only returns the selectedItem in the list. I've found little on Subquery. Is there a guru out there that can help me refine this?

预先感谢您的帮助!

编辑9June

好消息是Dan的代码我可以填充tableview的项目!不幸的是排名数字为0.

The good news is with Dan's code I'm able to populate the tableview with items! Unfortunately ranking numbers are 0.

解决方案
我原本试图通过ID搜索标记,而不是名称。注意'rankingExpressionDescriptionForTags:'中的两个谓词选项:我没有我的标签的唯一标识符,并使用两个选项中的第二个。感谢Dan!

Solution I originally tried searching for tags by ID rather than name. Note the two predicate options in 'rankingExpressionDescriptionForTags:' I do not have unique identifier to my tags and use the second of the two options. Thanks Dan!

推荐答案

谓词只是开始。

A predicate is only the beginning.

首先,请查看非常相似的问题。

First take a look at THIS VERY similar question.

假设您的模型有 Item 实体,在多对多关系中相关:

Item.tags < > Tag.items

Assuming your model has an Item and Tag entities, related in a many-to-many relationship:
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来显示这些项目

  1. The resulting array contains dictionaries
  2. (AFAIK) You will have to sort the resulting array in-memory after the fetch if you like to sort by ranking
  3. You cannot use a fetched results controller to track changes in these objects
  4. You can use a FRC to display these items

这篇关于谓词子查询通过匹配标记返回项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆