Im having trouble extracting data from a API, i would like to use for a school project..
The link to the API i here
Or here's a sample of the API output
{
"help": "http://www.odaa.dk/api/3/action/help_show?name=datastore_search",
"success": true,
"result": {
"resource_id": "2a82a145-0195-4081-a13c-b0e587e9b89c",
"fields": [
{
"type": "int4",
"id": "_id"
},
{
"type": "text",
"id": "date"
},
{
"type": "text",
"id": "garageCode"
},
{
"type": "int4",
"id": "totalSpaces"
},
{
"type": "int4",
"id": "vehicleCount"
}
],
"records": [
{
"date": "2015/11/11 03:50:07",
"vehicleCount": 62,
"_id": 1,
"totalSpaces": 65,
"garageCode": "NORREPORT"
},
{
"date": "2015/11/11 03:50:07",
"vehicleCount": 512,
"_id": 2,
"totalSpaces": 512,
"garageCode": "SKOLEBAKKEN"
},
{
"date": "2015/11/11 03:50:07",
"vehicleCount": 236,
"_id": 3,
"totalSpaces": 1240,
"garageCode": "SCANDCENTER"
},
{
"date": "2015/11/11 03:50:07",
"vehicleCount": 40,
"_id": 4,
"totalSpaces": 953,
"garageCode": "BRUUNS"
},
{
"date": "2015/11/11 03:50:07",
"vehicleCount": 2932,
"_id": 5,
"totalSpaces": 142,
"garageCode": "BUSGADEHUSET"
},
{
"date": "2015/11/11 03:50:07",
"vehicleCount": 18,
"_id": 6,
"totalSpaces": 383,
"garageCode": "MAGASIN"
},
{
"date": "2015/11/11 03:50:07",
"vehicleCount": 3,
"_id": 7,
"totalSpaces": 210,
"garageCode": "KALKVAERKSVEJ"
},
{
"date": "2015/11/11 03:50:07",
"vehicleCount": 255,
"_id": 8,
"totalSpaces": 700,
"garageCode": "SALLING"
},
{
"date": "2015/11/11 03:50:07",
"vehicleCount": 0,
"_id": 9,
"totalSpaces": 0,
"garageCode": "DOKK1"
},
{
"date": "2015/11/11 03:50:07",
"vehicleCount": 34,
"_id": 10,
"totalSpaces": 449,
"garageCode": "Navitas"
},
{
"date": "2015/11/11 03:50:07",
"vehicleCount": 105,
"_id": 11,
"totalSpaces": 105,
"garageCode": "NewBusgadehuset"
},
{
"date": "2015/11/11 03:50:07",
"vehicleCount": 9,
"_id": 12,
"totalSpaces": 319,
"garageCode": "Urban Level 1"
},
{
"date": "2015/11/11 03:50:07",
"vehicleCount": 15,
"_id": 13,
"totalSpaces": 654,
"garageCode": "Urban Level 2+3"
}
],
"_links": {
"start": "/api/action/datastore_search?resource_id=2a82a145-0195-4081-a13c-b0e587e9b89c",
"next": "/api/action/datastore_search?offset=100&resource_id=2a82a145-0195-4081-a13c-b0e587e9b89c"
},
"total": 13
}
}
I would like to extract the cells called "vehicleCount" and "_id", but i seems I can't figure out how to do it :(
$json = file_get_contents('http://www.odaa.dk/api/action/datastore_search?resource_id=2a82a145-0195-4081-a13c-b0e587e9b89c');
$json = json_decode($json);
echo $json->fields->_id;
I have tried many different ways, but now loss of ideas and its 4 o'clock in the morning, so hopefully someone can help me.
if you want to extract the cells vehicleCount and _id
This is my solution for you:
<?php
$json = file_get_contents('http://www.odaa.dk/api/action/datastore_search?resource_id=2a82a145-0195-4081-a13c-b0e587e9b89c');
$json = json_decode($json);
foreach ($json->result->records as $val) {
echo "_id = " .$val->_id . " vehicleCount = " . $val->vehicleCount . "<br>";
}
?>
$json->result->records[0]->_id
Related
So I'm having a strange problem with Doctrine that I don't understand and need help with. Essentially, I am running quite a complex query due to the nature of my database and its various joins and for some reason the response when I grab try to grab all records from my database is returning my entities incorrectly.
See my doctrine query below:
$subQuery = $this->_em->createQueryBuilder()
->from(Product::class, 'ex')
->select('ppsi.id')
->join('ex.productSpecificationItems', 'ppsi')
->where('ex.id = p.id');
$subQuery = $subQuery->getDQL();
$subQuery2 = $this->_em->createQueryBuilder()
->from(Product::class, 'ex2')
->select('ppoiv.id')
->join('ex2.productOptionItemValues', 'ppoiv')
->where('ex2.id = p.id');
$subQuery2 = $subQuery2->getDQL();
$subQuery3 = $this->_em->createQueryBuilder()
->from(Product::class, 'ex3')
->select('poie.id')
->join('ex3.productOptionItems', 'poie')
->where('ex3.id = p.id');
$subQuery3 = $subQuery3->getDQL();
$qb = $this->createQueryBuilder('p')
->select('p, pc, psc, i, po, poi, poiv, ps, psi')
->join('p.productCategory', 'pc')
->leftJoin('p.productSubCategory', 'psc')
->leftJoin('p.images', 'i')
->leftJoin('p.productOptions', 'po')
->leftJoin('p.productSpecifications', 'ps')
->leftJoin('ps.productSpecificationItems', 'psi', Join::WITH, 'psi.id IN (' . $subQuery. ')')
->leftJoin('po.productOptionItems', 'poi', Join::WITH, 'poi.id IN (' . $subQuery3. ')')
->leftJoin('poi.productOptionItemValue', 'poiv', Join::WITH, 'poiv.id IN (' . $subQuery2. ')')
->addOrderBy('p.id', 'ASC');
The response of this causes some entities to have the productOptionItemValues either listed under the wrong productOptionItem, just causes blank records to return, or doesn't return them at all. See an example below (as a JSON for clarity):
{
"id": 373,
"name": "test",
"code": "test",
"url": "373-test",
"price": "1.00",
"stock": 1,
"description": "<p>fghfgh mnsdbfksdhfjk sd</p>\n",
"live": false,
"createdAt": "2022-03-17T14:45:35+00:00",
"updatedAt": "2022-03-17T15:12:44+00:00",
"featured": false,
"aggregateReviewScore": null,
"productCategory": {
"id": 2,
"name": "Hex Set Screws",
"url": "hex-set-screws"
},
"productSubCategory": {
"id": 12,
"name": "Nylon",
"url": "nylon"
},
"images": [],
"productOptions": [
{
"id": 1,
"name": "Colour",
"productOptionItems": {
"0": {
"id": 2,
"name": "Black",
"productOptionItemValue": [
{
"id": 1196,
"stock": 1,
"price": "1.00",
"useOwn": false
},
{
"id": 1201,
"stock": 1,
"price": "1.00",
"useOwn": false
},
{
"id": 1198,
"stock": 1,
"price": "1.00",
"useOwn": false
}
]
},
"1": {
"id": 8,
"name": "Yellow",
"productOptionItemValue": [
{
"id": 1197,
"stock": 1,
"price": "1.00",
"useOwn": false
}
]
},
"2": {
"id": 14,
"name": "Light Grey"
},
"3": null,
"4": {
"id": 15,
"name": "Mid Grey"
},
"7": null,
"8": {
"id": 20,
"name": "Light Blue"
},
"11": null,
"12": {
"id": 22,
"name": "Purple"
},
"13": null
}
},
{
"id": 2,
"name": "Pack Size",
"productOptionItems": [
{
"id": 3,
"name": "10",
"productOptionItemValue": [
{
"id": 1180,
"stock": 100,
"price": "10.00",
"useOwn": true
}
]
},
{
"id": 4,
"name": "100",
"productOptionItemValue": [
{
"id": 1181,
"stock": 10,
"price": "1000.00",
"useOwn": true
}
]
}
]
}
],
"productSpecifications": []
}
If I run the same query on a SINGLE product (so the same Doctrine Query as a above just with a p.id = :id WHERE added) it returns absolutely fine. See the response for that below (and the CORRECT response I am looking for):
{
"id": 373,
"name": "test",
"code": "test",
"url": "373-test",
"price": 1,
"stock": 1,
"description": "<p>fghfgh mnsdbfksdhfjk sd</p>\n",
"live": false,
"createdAt": "2022-03-17T14:45:35+00:00",
"updatedAt": "2022-03-17T15:12:44+00:00",
"featured": false,
"aggregateReviewScore": null,
"productCategory": {
"id": 2,
"name": "Hex Set Screws",
"url": "hex-set-screws"
},
"productSubCategory": {
"id": 12,
"name": "Nylon",
"url": "nylon"
},
"images": [],
"productOptions": [
{
"id": 1,
"name": "Colour",
"productOptionItems": [
{
"id": 2,
"name": "Black",
"productOptionItemValue": {
"id": 1196,
"stock": 1,
"price": 1,
"useOwn": false
}
},
{
"id": 7,
"name": "Red",
"productOptionItemValue": {
"id": 1201,
"stock": 1,
"price": 1,
"useOwn": false
}
},
{
"id": 8,
"name": "Yellow",
"productOptionItemValue": {
"id": 1197,
"stock": 1,
"price": 1,
"useOwn": false
}
},
{
"id": 14,
"name": "Light Grey",
"productOptionItemValue": {
"id": 1202,
"stock": 1,
"price": 1,
"useOwn": false
}
},
{
"id": 15,
"name": "Mid Grey",
"productOptionItemValue": {
"id": 1205,
"stock": 1,
"price": 1,
"useOwn": false
}
},
{
"id": 20,
"name": "Light Blue",
"productOptionItemValue": {
"id": 1203,
"stock": 1,
"price": 1,
"useOwn": false
}
},
{
"id": 22,
"name": "Purple",
"productOptionItemValue": {
"id": 1204,
"stock": 1,
"price": 1,
"useOwn": false
}
},
{
"id": 23,
"name": "Natural",
"productOptionItemValue": {
"id": 1198,
"stock": 1,
"price": 1,
"useOwn": false
}
}
]
},
{
"id": 2,
"name": "Pack Size",
"productOptionItems": [
{
"id": 3,
"name": "10",
"productOptionItemValue": {
"id": 1180,
"stock": 100,
"price": 10,
"useOwn": true
}
},
{
"id": 4,
"name": "100",
"productOptionItemValue": {
"id": 1181,
"stock": 10,
"price": 1000,
"useOwn": true
}
}
]
}
],
"productSpecifications": []
}
Any help or ideas would be greatly appreciated!
Let's consider the following JSON response. It is a list of station objects.
[
{
"id": 43,
"trucks": [
{
"id": 24,
"vehicleType": {
"id": 2,
"vehicleType": "VT",
"createdAt": 1622645476000,
"updatedAt": 1622645476000
},
"sensor": {
"id": 16,
"devId": "tutorial",
"readings": [
{
"id": 36296,
"interiorTemperature": 528.36,
"batteryTemperature": 528.36,
"batteryVoltage": 0,
"createdAt": 1623065279000,
"updatedAt": 1623065279000
}
],
"resolved": false,
"createdAt": 1622645598000,
"updatedAt": 1622650553000
},
"vehicleNumber": 123456,
"truckStatus": true,
"defaultBatteryVoltage": "12",
"batteryTempThreshold": 25,
"interiorTempThresholdMax": 30,
"interiorTempThresholdMin": 5,
"batteryVoltageThreshold": 11.5,
"createdAt": 1622645517000,
"updatedAt": 1622645663000
},
{
"id": 29,
"vehicleType": {
"id": 2,
"vehicleType": "VT",
"createdAt": 1622645476000,
"updatedAt": 1622645476000
},
"sensor": {
"id": 23,
"devId": "value",
"readings": [
{
"id": 36298,
"interiorTemperature": 10,
"batteryTemperature": 10,
"batteryVoltage": 10,
"createdAt": 1623074142000,
"updatedAt": 1623074142000
}
],
"resolved": false,
"createdAt": 1623074089000,
"updatedAt": 1623074089000
},
"vehicleNumber": 313215,
"truckStatus": true,
"defaultBatteryVoltage": "12",
"batteryTempThreshold": 50,
"interiorTempThresholdMax": 50,
"interiorTempThresholdMin": 50,
"batteryVoltageThreshold": 50,
"createdAt": 1623073365000,
"updatedAt": 1623073365000
}
],
"name": "value",
"city": "value",
"address": "value",
"zipCode": "value",
"createdAt": 1622645352000,
"updatedAt": 1622645352000
},
{
"id": 44,
"trucks": [
{
"id": 25,
"vehicleType": {
"id": 3,
"vehicleType": "AG",
"createdAt": 1622647436000,
"updatedAt": 1622647436000
},
"sensor": {
"id": 18,
"devId": "test",
"readings": [
null
],
"resolved": false,
"createdAt": 1622795394000,
"updatedAt": 1622795394000
},
"vehicleNumber": 123457,
"truckStatus": true,
"defaultBatteryVoltage": "24",
"batteryTempThreshold": 80,
"interiorTempThresholdMax": 50,
"interiorTempThresholdMin": -20,
"batteryVoltageThreshold": 11.5,
"createdAt": 1622645584000,
"updatedAt": 1623074846000
}
],
"name": "value",
"city": "value",
"address": "value",
"zipCode": "11112",
"createdAt": 1622645431000,
"updatedAt": 1622645431000
},
{
"id": 46,
"trucks": [
{
"id": 26,
"vehicleType": {
"id": 2,
"vehicleType": "VT",
"createdAt": 1622645476000,
"updatedAt": 1622645476000
},
"sensor": null,
"vehicleNumber": 979787,
"truckStatus": true,
"defaultBatteryVoltage": "12",
"batteryTempThreshold": 123,
"interiorTempThresholdMax": 123,
"interiorTempThresholdMin": 123,
"batteryVoltageThreshold": 123,
"createdAt": 1623064671000,
"updatedAt": 1623064671000
}
],
"name": "value",
"city": "value",
"address": "value",
"zipCode": "11111",
"createdAt": 1622918304000,
"updatedAt": 1622918304000
}
]
All stations have an id, a list of trucks, and some basic info (name, location etc). With PHP, I convert this to an array object. What I would like to achieve is to sort the array. Now I have managed to sort based on name or location. I used the following snipped:
usort($stations, function($a, $b) {
$retval = $a['name'] <=> $b['name'];
return $retval;
});
Now it's all nice but we would like to sort it based on the highest interior temperature read in a station. To make the station with the highest interior temperature be the 0th element in the list and the one with the lowest (or no reading at all) is the nth. I have tried playing around with usort but I had no results. Is it even possible to sort it like that?
I want to pull data from below JSON format using PHP (foreach loop).
User detail is correspondence to house detail and house detail correspondence to individual meter reading.
I want to show Username, Device_No and all meter_detail field. Please help me out.
{
"id": 7,
"Username": "user",
"Housename": "Leela",
"Houses_list": [{
"id": 1,
"Device_No": 1111,
"meter_detail": [{
"id": 1,
"flow": 12,
"date": "2020-02-13T12:05:14.709Z",
"opening": 5,
"volume": 1234
},
{
"id": 2,
"flow": 32,
"date": "2020-02-13T12:05:26.821Z",
"opening": 2,
"volume": 1235
}
]
},
{
"id": 2,
"Device_No": 231,
"meter_detail": [{
"id": 3,
"flow": 78,
"date": "2020-02-13T12:05:41.331Z",
"opening": 5,
"volume": 7854
}]
}
]
}
You need to convert the JSON to an array by using json_decode(). Then a couple of foreach loops would do work for you:
<?php
$json = '{
"id": 7,
"Username": "user",
"Housename": "Leela",
"Houses_list": [{
"id": 1,
"Device_No": 1111,
"meter_detail": [{
"id": 1,
"flow": 12,
"date": "2020-02-13T12:05:14.709Z",
"opening": 5,
"volume": 1234
},
{
"id": 2,
"flow": 32,
"date": "2020-02-13T12:05:26.821Z",
"opening": 2,
"volume": 1235
}
]
},
{
"id": 2,
"Device_No": 231,
"meter_detail": [{
"id": 3,
"flow": 78,
"date": "2020-02-13T12:05:41.331Z",
"opening": 5,
"volume": 7854
}]
}
]
}';
$input = json_decode($json, true);
echo 'Username: '.$input['Username'].'<br>';
foreach ($input['Houses_list'] as $device){
echo '<br>Device No: '.$device['Device_No'].'<br>';
foreach ($device['meter_detail'] as $metrics){
echo '<table style="border: 1px solid black">';
foreach ($metrics as $key => $metric){
echo '<tr><td>'.$key.'</td><td>'.$metric.'</td></tr>';
}
echo '</table>';
}
}
?>
Output:
if you see this code:
use ResponseHandler;
public function search(SoundFilter $soundFilter) {
$sounds = Sound::query();
$sounds->filter($soundFilter);
// dd($sounds->toSql());
$sounds = $sounds->paginate(1);
$this->setResponseStatus(1);
$this->setResponseStatusCode(200);
$this->setResponseData([
'sounds' => new SoundsCollection($sounds),
]);
$this->ajaxResponse();
return $this->response();
}
i want soundsCollection($sounds) returen paginate result but it will send only data
{
"status": 1,
"messages": [],
"statusCode": 200,
"data": {
"sounds": [
{
"id": 1,
"name": "منی که عشق با روضه فهمیدم",
"slug": "",
"type": 2,
"description": "<p dir=\"rtl\" style=\"text-align:center\"><strong>متن شعر<\/strong><\/p>",
"likes": 0,
"downloads": 0,
"views": 0,
"created_at": "2019-08-02 20:09:45",
"updated_at": "2019-08-03 18:45:49",
"sort_order": 0,
"status": 1,
}
]
}
}
but when i do this code :
$sounds = Sound::query();
$sounds->filter($soundFilter);
// dd($sounds->toSql());
$sounds = $sounds->paginate(1);
$this->setResponseStatus(1);
$this->setResponseStatusCode(200);
// $this->setResponseData([
//// 'sounds' => new SoundsCollection($sounds),
//// ]);
$this->ajaxResponse();
return new SoundsCollection($sounds);
i will get pagination result
{
"data": [
{
"id": 1,
"name": "منی که عشق با روضه فهمیدم",
"slug": "",
"type": 2,
"description": "<p dir=\"rtl\" style=\"text-align:center\"><strong>متن شعر<\/strong><\/p>",
"likes": 0,
"downloads": 0,
"views": 0,
"created_at": "2019-08-02 20:09:45",
"updated_at": "2019-08-03 18:45:49",
"sort_order": 0,
"status": 1,
}
],
"links": {
"first": "http:\/\/madahi.test\/api\/v1.0\/search?page=1",
"last": "http:\/\/madahi.test\/api\/v1.0\/search?page=3",
"prev": null,
"next": "http:\/\/madahi.test\/api\/v1.0\/search?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 3,
"path": "http:\/\/madahi.test\/api\/v1.0\/search",
"per_page": 1,
"to": 1,
"total": 3
}
}
which function i should call or waht i should do to get same result but with my custom response handler how to force collection return paginate result
i want i have link, meta in first result
i found it and share it for other people if have same problem:
because i use seprate ResponseHandler and it will reutrn an JsonResponse object
it is the data i send to resposnse with responseHandler
// trait : ResponseHandler.php
new JsonResponse($json, $json['statusCode'], $this->headers);
and when i call this code it will retun another JsonResponse
'sounds' => new SoundsCollection($sounds),
// Or
'sounds' => (new SoundsCollection($sounds))->toResponse($request)
so the above JsonResponse will ignore pagination data the solution is :
'sounds' => (new SoundsCollection($sounds))->toResponse($request)->getData()
and it will work
{
"status": 1,
"messages": [],
"statusCode": 200,
"data": {
"sounds": {
"data": [
{
"id": 1,
"name": "منی که عشق با روضه فهمیدم",
"slug": "",
"type": 2,
"description": "<p dir=\"rtl\" style=\"text-align:center\"><strong>متن شعر<\/strong><\/p>",
"likes": 0,
"downloads": 0,
"views": 0,
"created_at": "2019-08-02 20:09:45",
"updated_at": "2019-08-03 18:45:49",
"sort_order": 0,
"status": 1,
}
],
"links": {
"first": "http:\/\/madahi.test\/api\/v1.0\/search?page=1",
"last": "http:\/\/madahi.test\/api\/v1.0\/search?page=3",
"prev": null,
"next": "http:\/\/madahi.test\/api\/v1.0\/search?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 3,
"path": "http:\/\/madahi.test\/api\/v1.0\/search",
"per_page": 1,
"to": 1,
"total": 3
}
}
}
}
I'm using FOSElasticaBundle with Symfony2 on my project and there are entry and user tables on MySQL database and each entry belongs to one user.
I want to get just one entry per a user among the whole entries from the database.
Entries Representation
[
{
"id": 1,
"name": "Hello world",
"user": {
"id": 17,
"username": "foo"
}
},
{
"id": 2,
"name": "Lorem ipsum",
"user": {
"id": 15,
"username": "bar"
}
},
{
"id": 3,
"name": "Dolar sit amet",
"user": {
"id": 17,
"username": "foo"
}
},
]
Expected result is:
[
{
"id": 1,
"name": "Hello world",
"user": {
"id": 17,
"username": "foo"
}
},
{
"id": 2,
"name": "Lorem ipsum",
"user": {
"id": 15,
"username": "bar"
}
}
]
But it returns all entries on table. I've tried to add an aggregation to my elasticsearch query and nothing changed.
$distinctAgg = new \Elastica\Aggregation\Terms("distinctAgg");
$distinctAgg->setField("user.id");
$distinctAgg->setSize(1);
$query->addAggregation($distinctAgg);
Is there any way to do this via term filter or anything else? Any help would be great. Thank you.
Aggregations are not easy to understand when you are used to MySQL group by.
The first thing, is that aggregations results are not returned in hits, but in aggregations. So when you get the result of your search, you have to get aggregations like that :
$results = $search->search();
$aggregationsResults = $results->getAggregations();
The second thing is that aggregations wont return you the source. With the aggregation of your example, you will only know that you have 1 user with ID 15, and 2 users with ID 15.
E.g. with this query :
{
"query": {
"match_all": {}
},
"aggs": {
"byUser": {
"terms": {
"field": "user.id"
}
}
}
}
Result:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 3,
"max_score": 1,
"hits": [ ... ]
},
"aggregations": {
"byUser": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": 17,
"doc_count": 2
},
{
"key": 15,
"doc_count": 1
}
]
}
}
}
If you want to get results, the same way you would do with a GROUP BY in MySQL, you have to use a top_hits sub-aggregation:
{
"query": {
"match_all": {}
},
"aggs": {
"byUser": {
"terms": {
"field": "user.id"
},
"aggs": {
"results": {
"top_hits": {
"size": 1
}
}
}
}
}
}
Result:
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 3,
"max_score": 1,
"hits": [ ... ]
},
"aggregations": {
"byUser": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": 17,
"doc_count": 2,
"results": {
"hits": {
"total": 2,
"max_score": 1,
"hits": [
{
"_index": "test_stackoverflow",
"_type": "test1",
"_id": "1",
"_score": 1,
"_source": {
"id": 1,
"name": "Hello world",
"user": {
"id": 17,
"username": "foo"
}
}
}
]
}
}
},
{
"key": 15,
"doc_count": 1,
"results": {
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "test_stackoverflow",
"_type": "test1",
"_id": "2",
"_score": 1,
"_source": {
"id": 2,
"name": "Lorem ipsum",
"user": {
"id": 15,
"username": "bar"
}
}
}
]
}
}
}
]
}
}
}
More informations on this page : https://www.elastic.co/blog/top-hits-aggregation