如何在appleitunes搜索api中组合实体类型搜索



在itunes搜索api文档中,有一个搜索艺术家的例子,名为maroon,url如下所示:

https://itunes.apple.com/search?term=maroon&entity=allArtist&attribute=allArtistTerm

这会返回50多个结果,它们的开头是这样的:

{
    "resultCount": 50,
    "results": [
        {
            "wrapperType": "artist",
            "artistType": "Artist",
            "artistName": "Maroon 5",
            "artistLinkUrl": "https://itunes.apple.com/us/artist/maroon-5/id1798556?uo=4",
            "artistId": 1798556,
            "amgArtistId": 529962,
            "primaryGenreName": "Pop",
            "primaryGenreId": 14,
            "radioStationUrl": "https://itunes.apple.com/station/idra.1798556"
        },
        {
            "wrapperType": "artist",
            "artistType": "Software Artist",
            "artistName": "MaroonEntertainment",
            "artistLinkUrl": "https://itunes.apple.com/us/artist/maroonentertainment/id537029262?uo=4",
            "artistId": 537029262,
            "radioStationUrl": "https://itunes.apple.com/station/idra.537029262"
        },

这很好。然而,我的问题是:我想创建一个尽可能具体的搜索查询,通过组合对艺术家、歌曲名称和专辑名称的搜索。。

例如,我得到了这首歌:

  • 歌曲:跨越大分水岭
  • 相册:大分水岭
  • 艺术家:Semisonic

我只能搜索艺术家的名字:

https://itunes.apple.com/search?term=Semisonic&entity=allArtist&attribute=allArtistTerm

我只能搜索歌曲术语:

https://itunes.apple.com/search?term=Across the Great Divide&entity=song&attribute=songTerm

我只能搜索专辑名称:

https://itunes.apple.com/search?term=Great Divide&entity=album&attribute=albumTerm

然而,这些人都没有给我想要的结果(我可以在大约50个其他人中找到我要找的结果……但我只希望搜索查询足够具体,以避免任何客户端过滤之类的事情)。

如何组合这些搜索?如果我只是把两个搜索加在一起(在这个例子中,我同时搜索歌曲艺术家):

https://itunes.apple.com/search?term=Across the Great Divide&entity=song&attribute=songTerm&term=Semisonic&entity=allArtist&attribute=allArtistTerm

然后苹果将简单地忽略第一个搜索类型(即歌曲),并只返回艺术家的搜索结果)。

想法?

这更多的是一个"变通方法"的答案。。但这是我正在使用的解决方案。。不如把爱传播出去吧?

这是一个100%的客户端解决方案(即itunes音乐的整个数据库可以下载到我自己的服务器中……然后我可以围绕它创建所有的搜索包装……但这本身就是一个项目)。

这就是我得到的:

// this is just a wrapper around the apple search api.. it makes your 
// average joe http get request
[[AppleServer shared] searchForSongWithTitle:track.title andAlbumName:track.albumName completion:^(NSArray *results, NSError *error){
    if ([results count] >0) {
        NSLog(@"[%d] unfiltered songs retrieved from apple search api", [results count]);
        NSDictionary *filteredResult = [[self class] filterResults:results ToMatchTrack:track];
        if (!filteredResult) {
            NSLog(@"Filtering may be too strict, we got [%d] results from apple search api but none past our filter", [results count]);
            return;
        }
        .. process results

+ (NSDictionary *)filterResults:(NSArray *)results ToMatchTrack:(VBSong *)track
{
    NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(NSDictionary *evaluatedTrack, NSDictionary *bindings){    
        BOOL result =
         ([track.title isLooselyEqualToString:evaluatedTrack[@"trackName"]] &&
          [track.artistName isLooselyEqualToString:evaluatedTrack[@"artistName"]] &&
          [track.albumName isLooselyEqualToString:evaluatedTrack[@"collectionName"]]);
        NSLog(@"match?[%d]", result);
        return result;
    }];
    return [[results filteredArrayUsingPredicate:predicate] firstObject];
}

这里的关键方法是CCD_ 1。。它被定义在NSString类别中,如下所示:

/**
 * Tests if one string equals another substring, relaxing the following contraints
 *   - one string can be a substring of another
 *   - it's a case insensitive comparison
 *   - all special characters are removed from both strings
 *
 *     ie this should return true for this comparison:
 *     - comparing self:"Circus One (Presented By Doctor P and Flux Pavilion)" 
                and str:"Circus One presented by Doctor P"
 *
 * @param str string to compare self against
 * @return if self is the same as str, relaxing the contraints described above
 */
- (BOOL)isLooselyEqualToString:(NSString *)str
{
    return [[self removeSpecialCharacters] containSubstringBothDirections:[str removeSpecialCharacters]];
}
/**
 * Tests if one string is a substring of another
 *     ie this should return true for both these comparisons:
 *     - comparing self:"Doctor P & Flux Pavilion" and substring:"Flux Pavilion"
 *     - comparing self:"Flux Pavilion" and substring:"Doctor P & Flux Pavilion"
 *
 * @param substring to compare self against
 * @return if self is a substring of substring
 */
-(BOOL)containSubstringBothDirections:(NSString*)substring
{
    if (substring == nil) return self.length == 0;
    if ([self rangeOfString:substring options:NSCaseInsensitiveSearch].location == NSNotFound) {
        if ([substring rangeOfString:self options:NSCaseInsensitiveSearch].location == NSNotFound) {
            return NO;
        } else {
            return YES;
        }
    } else {
        return YES;
    }
}
- (NSString *)removeSpecialCharacters
{
    NSMutableCharacterSet *specialCharsSet = [[NSCharacterSet letterCharacterSet] mutableCopy];
    [specialCharsSet formUnionWithCharacterSet:[NSCharacterSet whitespaceCharacterSet]];
    return [[self componentsSeparatedByCharactersInSet:[specialCharsSet invertedSet]] componentsJoinedByString:@""];
}

奖金这是我们目前正在使用的解决方案。。我完全知道可能会出现一些术语来破坏这个算法。。因此,我们对此进行了一个单元测试,我们逐步添加项,以确保我们不断改进算法,同时不会导致回归错误。。如果我在这个答案上得到足够的票数,我会把它贴出来的。

abbood,

对不起,你不能从这里到那里!(除非其他人发现了新东西。)

我目前正在开发一个应用程序,它将组合多个查询的结果。

对于更具冒险精神的公司,苹果向附属合作伙伴提供"iTunes和应用商店的完整元数据数据源"。为了使用它,我将在云中放置一个数据库服务,并使用它进行更详细的查询和显示搜索API未返回的详细信息。

如果我完成了我的应用程序,并且它实际上被5个人以上使用,我可能会考虑做整个数据库版本。

David

相关内容

  • 没有找到相关文章