1

I am currently developing a web application that will find artists and their associates titles. To do this, I decided to parse the API MusicBrainz, through this package (which documentation is here).

Suppose I already have the artist mbid (unique identifier for MusicBrainz).

The problem is that if I do a search on David Guetta (mbid = 302bd7b9-d012-4360-897a-93b00c855680) for example, the script tells me that the number of releases is 196. However, the API provides 100 maximum results per request.

// Instantiate a MusicBrainz object
$brainz = new MusicBrainz(new GuzzleHttpAdapter(new Client()));
$brainz->setUserAgent('ApplicationName', '0.2', 'http://example.com');

$limit = 100;
$offset = 0;

$includes = array('labels', 'recordings');
try {
  $details = $brainz->browseRelease('artist', '302bd7b9-d012-4360-897a-93b00c855680', $includes, $limit, $offset);
  print_r($details);
} catch (Exception $e) {
  print $e->getMessage();
}

The function browseRelease below allows us to define such parameters as limit and offset.

public function browseRelease($entity, $mbid, $includes = array(), $limit = 25, $offset = null, $releaseType = array(), $releaseStatus = array())
{
  if (!in_array($entity, array('artist', 'label', 'recording', 'release-group'))) {
    throw new Exception('Invalid browse entity for release');
  }
  return $this->browse(
    new Filters\ReleaseFilter(array()),
      $entity,
      $mbid,
      $includes,
      $limit,
      $offset,
      $releaseType,
      $releaseStatus
  );
}

Now we come to my real question in this post.

If I defined $limit = 100 and $offset = 0 for the first query, I don't understand how to change these values depending on the number of total releases, and thus get the results that are between 100 and 196 (in this example).

w3spi
  • 4,380
  • 9
  • 47
  • 80
  • 1
    I dont know php but dont you just set $offset=100 in the first query to get the next set of records – Paul Taylor Jun 05 '15 at 08:14
  • 1
    say you have 150 results. First call you do: `$offset = 0`. Then you call again with `$offset = 100`. The limit doesn't matter: if the limit is 100, but there are only 50 results available, it will give you 50 results, starting from the offset value. – Jordumus Jun 05 '15 at 08:36
  • 1
    Maybe mark his answer as accepted? That's the way to say "thank you" on SO when someone helps you solve the problem. – N.B. Jun 05 '15 at 09:13

2 Answers2

2

As of this question, I'll post my answer as a "real answer":

Pseudolanguage

Given: 150 results. You can define: offset and limit. But: max limit is 100 results.

You'll need 2 calls, because you can only get 100 results at a time. This is how you could solve it:

Call 1:

Offset: 0
Limit: 100
//Returns results 0 to 99.

Call 2:

Offset: 100
Limit: [OPTIONAL] 100
//Returns resuls 100 to 199. As there are only 150 results in total, it will automatically return 100 to 150

Now, we could also make this automatic with a loop:

limit = 100
for (var i = 0; i < maxResults; i=i+100)
{
    offset = i
    GetResults(offset,limit);
}
Community
  • 1
  • 1
Jordumus
  • 2,763
  • 2
  • 21
  • 38
  • Don't understand why it returns an array of size = 25 and then an array of size = 96 ... What's the problem ? (Default limit value = 25, but why it is doing that ?) – w3spi Jun 05 '15 at 19:09
1

The pseudo code answer from Jordumus is correct, but this is how you have to modify your code to make it work.

$limit = 100;
$offset = 0;
$release_count = 0;

$includes = array('labels', 'recordings');
do {
  if ($offset != 0) sleep(1);
  try {
    $details = $brainz->browseRelease('artist', '302bd7b9-d012-4360-897a-93b00c855680', $includes, $limit, $offset);
    $release_count = $details['release-count'];
    print_r($details);
  } catch (Exception $e) {
    print $e->getMessage();
  }
  $offset += $limit;
} while ($offset < $release_count);

Note that it would be enough to set $release_count the first time, since the value doesn't change, but resetting it also doesn't hurt.

I added a sleep in there because of the required rate limiting which doesn't seem to be implemented in the PHP library.

Community
  • 1
  • 1
JonnyJD
  • 2,593
  • 1
  • 28
  • 44
  • Wow, that's working !!!!! I have edited your post, because print_r returned error 502 bad gateway. I have put var_dump instead. Thank you very much ! – w3spi Jun 06 '15 at 12:23
  • The 502 has nothing to do with `print_r`/`var_dump` since the 502 error/exception is thrown on `browseRelease()`. The musicbrainz server has these kinds of hiccups from time to time. For this reason you should have some (manual or automatic) "retry" mechanism when errors like that come up. – JonnyJD Jun 06 '15 at 16:04
  • Indeed, after several tests, I have seen that mb server didn't work and then it work without any changes. Yes. I will put exceptions to see which request doesn't work. Thank you ! – w3spi Jun 06 '15 at 16:07