halaxa / json-machine

Efficient, easy-to-use, and fast PHP JSON stream parser

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Get JSON object properties (non-iterable elements)

quinncomendant opened this issue · comments

I'm loading JSON from the FDA (example query) which contains meta values which are non-arrays. I would like to be able to retrieve the last_updated and total values from this JSON:

{
  "meta": {
    "terms": "https://open.fda.gov/terms/",
    "license": "https://open.fda.gov/license/",
    "last_updated": "2019-12-20",
    "results": {
      "skip": 0,
      "limit": 105845,
      "total": 105845
    }
  },
  "results": [

    "… 105845 records here …"

  ]
}

I've tried to get the values from meta like this, but it doesn't work because meta is not an iterable object:

$meta = \JsonMachine\JsonMachine::fromFile($import_file, '/meta');
foreach ($meta as $key => $val) {
    if ($key == 'last_updated') {
        $last_updated = $val;
    }
}

Is there a way to get these values using JsonMachine?

Edit: I also tried this:

$last_updated = \JsonMachine\JsonMachine::fromFile($import_file, '/meta/last_updated');
echo $last_updated;
echo $last_updated->current();
echo end($last_updated);

I'm not familiar with using IteratorAggregate, so I'm not sure how to get a value from the $last_updated object.

Hi, JsonMachine::fromFile($import_file, '/meta'); should work, because meta key is iterable. I've just tried it with your example data and it worked. Are you sure you didn't mistype something? Can you make failing test for your use case and create PR?

You're right, my code works. The problem is, I assumed JsonMachine would stop processing when it reached the end of the /meta node, and when it didn't return right away, I thought it was stuck (it would finally return after a few minutes when EOF is reached). So I just needed to add a break:

$meta = \JsonMachine\JsonMachine::fromFile($import_file, '/meta');
foreach ($meta as $key => $val) {
    if ($key == 'last_updated') {
        $last_updated = $val;
        break;
    }
}

Yes, break stops any further processing. It could be mentioned in README. But it's true that JSON Machine should stop processing when the end of the iterated subtree is reached. I'll make an issue for it.

Hi @halaxa
Is there a way to stop iterating the subtree? I have a JSON file of 500 GB with 10 subtrees. Right now the code would continue iterating the subtree and thus wasting alot of time doing so.
You mentioned in your last comment that you would create an issue regarding this but I am not able to find it. Is this fixed?

You're correct, I forgot to do it. Can you make it please? Right now the only solution would be to break form it. But I see that you do not know which item is the last one in your subtree, do you?

@quinncomendant You can newly access a non-iterable filed directly using /meta/last_updated json pointer. It's implemented on master. See README for more details.