I have a array, but for now, the array is still based on id_order, , like this :
here my controller
public function detail()
{
$data = Order::with('detail')->get();
return $data;
}
result:
[
{
"id": 1, //id_order
"order_number" : "IT.123.76",
"status" : "Pending",
"details" : [
{
"id" : 1,
"id_order" : 1,
"id_item" : 2, //based from this
"name" : "Avocado Juice",
"qty" : 7
},
{
"id" : 2,
"id_order" : 1,
"id_item" : 3, //based from this
"name" : "Orange Juice",
"qty" : 2
},
{
"id" : 3,
"id_order" : 1,
"id_item" : 5, //based from this
"name" : "Mango Juice",
"qty" : 1
}
]
},
{
"id": 2, //id_order
"order_number" : "IT.123.78",
"status" : "Pending",
"details" : [
{
"id" : 4,
"id_order" : 2,
"id_item" : 2, //based from this
"name" : "Avocado Juice",
"qty" : 1
},
{
"id" : 5,
"id_order" : 2,
"id_item" : 9, //based from this
"name" : "Ice Tea",
"qty" : 2
}
]
}
}
]
How to change the structure of the array to be like this(based id_item and name item becomes the key in each element) and also for qty per item calculated, for example = avocado juice has 2 orders, first order has qty: 7 and second order qty: 1 then sums 8 results?
[
{
"qty_total" : 8, // from 7+1 in avocado juice
"Avocado Juice" : [
{
"id" : 1, //From id_order
"id_item" : 2, //Avocado Juice
"order_number" : "IT.123.76",
"qty" : 7
},
{
"id" : 2, //From id_order
"id_item" : 2, //Avocado Juice
"order_number" : "IT.123.78",
"qty" : 1
}
]
},
{
"qty_total" : 2,
"Orange Juice" : [
{
"id" : 1, //From id_order
"id_item" : 3, //Orange Juice
"order_number" : "IT.123.76",
"qty" : 2
}
]
},
{
"qty_total" : 1,
"Mango Juice" : [
{
"id" : 2, //From id_order
"id_item" : 5, //Mango Juice
"order_number" : "IT.123.76", //order_number Id_order 1
"qty" : 1
}
]
},
{
"qty_total" : 2,
"Ice Tea" : [
{
"id" : 1, //From id_order
"id_item" : 9, //Ice Tea
"order_number" : "IT.123.78",
"qty" : 2
}
]
},
]
Thanks for advance
You can try something like this.
const orders = [
{
"id": 1, //id_order
"order_number": "IT.123.76",
"status": "Pending",
"details": [
{
"id": 1,
"id_order": 1,
"id_item": 2, //based from this
"name": "Avocado Juice",
"qty": 7
},
{
"id": 2,
"id_order": 1,
"id_item": 3, //based from this
"name": "Orange Juice",
"qty": 2
},
{
"id": 3,
"id_order": 1,
"id_item": 5, //based from this
"name": "Mango Juice",
"qty": 1
}
]
}, {
"id": 2,
"order_number": "IT.123.78",
"status": "Pending",
"details": [
{
"id": 4,
"id_order": 2,
"id_item": 2, //based from this
"name": "Avocado Juice",
"qty": 1
},
{
"id": 5,
"id_order": 2,
"id_item": 9, //based from this
"name": "Ice Tea",
"qty": 2
}
]
}
];
var ordersById = {};
orders.forEach((order) => {
order.details.forEach((detail) => {
// ToDo: filter out completed/nonpending orders
let orderGroup;
if (!ordersById[detail.id_item]) {
orderGroup = {qty_total: detail.qty};
orderGroup[detail.name] = [{id: detail.id_order, id_item: detail.id_item, order_number: order.order_number, qty: detail.qty}];
ordersById[detail.id_item] = orderGroup;
} else {
orderGroup = ordersById[detail.id_item];
orderGroup.qty_total += detail.qty;
orderGroup[detail.name].push([{id: detail.id_order, id_item: detail.id_item, order_number: order.order_number, qty: detail.qty}]);
}
});
});
const result = Object.keys(ordersById).map((order_id) => { return ordersById[order_id];});;
console.log(result);
Related
please check i have below total 3 tables. now when i get claim records i want to get all subcategories from same category using relationships. i have stored subcategory id in my claimdata table. i want to create drop-down dynamically for all claimdata records that's why i need all subcategories from same parent category with each claimdata records
Table1 : Category
id
Category
1
cat1
2
cat2
Table2 : SubCategory
id
Category_id
SubCategory
3
1
subcat1
4
1
subcat2
5
2
subcat3
6
2
subcat4
Table2 : ClaimData
id
subcategory_id
claimName
1
3
abc
2
3
def
2
5
xyz
2
6
pqr
relationship is
public function subcategories()
{
$this->hasMany(SubCategory::class,'id','subcategory_id');
}
my query is
$claimdata = ClaimsData::with('subcategories')->get();
currently it returns only related one subcategory but we wants all subcategory list from same parent category.
[{
"id" : 1,
"subcategory_id" : 3,
"claimName" : "abc",
"subcategories" : [{
"id" : 3,
"category_id" : 1,
"SubCategory" : "subcat1"
}]
},
{
"id" : 2,
"subcategory_id" : 3,
"claimName" : "def",
"subcategories" : [{
"id" : 3,
"category_id" : 1,
"SubCategory" : "subcat1"
}]
},....]
expected output :
[{
"id" : 1,
"subcategory_id" : 3,
"claimName" : "abc",
"subcategories" : [{
"id" : 3,
"category_id" : 1,
"SubCategory" : "subcat1"
},
{
"id" : 4,
"category_id" : 1,
"SubCategory" : "subcat2"
}]
},
{
"id" : 2,
"subcategory_id" : 3,
"claimName" : "def",
"subcategories" : [{
"id" : 3,
"category_id" : 1,
"SubCategory" : "subcat1"
},
{
"id" : 4,
"category_id" : 1,
"SubCategory" : "subcat2"
}]
},
{
"id" : 3,
"subcategory_id" : 5,
"claimName" : "def",
"subcategories" : [{
"id" : 5,
"category_id" : 2,
"SubCategory" : "subcat3"
},
{
"id" : 6,
"category_id" : 2,
"SubCategory" : "subcat4"
}]
},
{
"id" : 4,
"subcategory_id" : 6,
"claimName" : "def",
"subcategories" : [{
"id" : 5,
"category_id" : 2,
"SubCategory" : "subcat3"
},
{
"id" : 6,
"category_id" : 2,
"SubCategory" : "subcat4"
}]
}]
I've inherited an old project that runs on MySql 5.6 and Zend FW 2. I'm trying to run a query that will give the same results as JSON_OBJECT() but mysql 5.6 doesn't support that.
Basically I have 2 tables
Receipts -
receipt_id
phone
amount
status
1
7777777777
5682
Success
2
8888888888
4586
Success
3
5555555555
7589
Success
Receipt_Item -
receipt_id
item_id
quantity
price
1
1
23
5682
1
2
30
5682
2
1
10
7589
3
1
23
4355
3
2
41
3665
And need to get this output
[
{
"receipt_id": 1,
"phone": "7777777777",
"amount": "5682",
"status": "Success",
"receipt_item" : [
{
"receipt_id" : 1,
"item_id" : 1,
"quantity" : 23,
"price" : 5682
},
{
"receipt_id" : 1,
"item_id" : 2,
"quantity" : 30,
"price" : 5682
}
]
},
{
"receipt_id": 2,
"phone": "8888888888",
"amount": "4586",
"status": "Success",
"receipt_item" : [
{
"receipt_id" : 2,
"item_id" : 1,
"quantity" : 10,
"price" : 7589
}
]
},
{
"receipt_id": 3,
"phone": "5555555555",
"amount": "7589",
"status": "Success",
"receipt_item" : [
{
"receipt_id" : 3,
"item_id" : 1,
"quantity" : 23,
"price" : 4355
},
{
"receipt_id" : 3,
"item_id" : 2,
"quantity" : 41,
"price" : 3665
}
]
}
]
Due to the version I cannot use JSON_OBJECT(). Is there any other way in sql to get this result.
If not can I post-process this in PHP to combine multiple objects with the same receipt_id and creating an inner array with combined receipt items?
Essentially turning this:
[
[
"receipt_id" => 1,
"phone" => "7777777777",
"amount" => "5682",
"status" => "Success",
"item_id" => 1,
"quantity" => 23,
"price" => 5682
],
[
"receipt_id" => 1,
"phone" => "7777777777",
"amount" => "5682",
"status" => "Success",
"item_id" => 1,
"quantity" => 23,
"price" => 5682
],
]
into this
[
[
"receipt_id" => 1,
"phone" => "7777777777",
"amount" => "5682",
"status" => "Success",
"receipt_item" => [
[
"item_id" => 1,
"quantity" => 23,
"price" => 5682
],
[
"item_id" => 2,
"quantity" => 30,
"price" => 5682
]
]
],
]
In PHP I can use array_unique() and array_column(), and then loop through the original array to get the result. But is there an in-built way to get there?
Thanks.
You can aggregate data on PHP side using array_reduce:
$output = array_reduce(
$input,
function($acc, $r) {
if (!isset($acc[$r["receipt_id"]])) {
$acc[$r["receipt_id"]] = [
"receipt_id" => $r["receipt_id"],
"phone" => $r["phone"],
"amount" => $r["amount"],
"status" => $r["status"],
"receipt_item" => []
];
}
$acc[$r["receipt_id"]]["receipt_item"][] = [
"item_id" => $r["item_id"],
"quantity" => $r["quantity"],
"price" => $r["price"]
];
return $acc;
},
[]
);
run PHP online
i have an array like this with position disordered i want to order the position like 123 123 123 12
[{
"id": 1,
"name": "ASDAS",
"position": 1,
},
{
"id": 2,
"name": "ASDAS",
"position": 1,
},
{
"id": 3,
"name": "ASDAS",
"position": 3,
},
{
"id": 4,
"name": "ASDAS",
"position": 2,
},
{
"id": 5,
"name": "ASDAS",
"position": 2,
},
{
"id": 6,
"name": "ASDAS",
"position": 3,
},
{
"id": 7,
"name": "ASDAS",
"position": 2,
},
{
"id": 8,
"name": "ASDAS",
"position": 1,
}
]
i want the order like that
[{
"id": 1,
"name": "ASDAS",
"position": 1,
},
{
"id": 4,
"name": "ASDAS",
"position": 2,
},
{
"id": 3,
"name": "ASDAS",
"position": 3,
},
{
"id": 2,
"name": "ASDAS",
"position": 1,
},
{
"id": 5,
"name": "ASDAS",
"position": 2,
},
{
"id": 6,
"name": "ASDAS",
"position": 3,
},
{
"id": 8,
"name": "ASDAS",
"position": 1,
},
{
"id": 7,
"name": "ASDAS",
"position": 2,
}
]
The below should do the trick. I assume your data is an array of objects.
First I order the array by ID and then seperate the items by group. Finally, I merge all the groups 1 item at a time. There is probably a better way to acheive what you are after but thought this might be a good starting point.
This will adapt to the max position value. For example, if one of the data items has a position of 4 you would end up with a position order: 1234 123 123 123 12... etc
<?php
$input = [
(object)[
"id" => 1,
"name" => "ASDAS",
"position" => 1,
],
(object)[
"id" => 2,
"name" => "ASDAS",
"position" => 1,
],
(object)[
"id" => 3,
"name" => "ASDAS",
"position" => 3,
],
(object)[
"id" => 4,
"name" => "ASDAS",
"position" => 2,
],
(object)[
"id" => 5,
"name" => "ASDAS",
"position" => 2,
],
(object)[
"id" => 6,
"name" => "ASDAS",
"position" => 3,
],
(object)[
"id" => 7,
"name" => "ASDAS",
"position" => 2,
],
(object)[
"id" => 8,
"name" => "ASDAS",
"position" => 1,
]
];
// Sort array by ID
usort($input, function($a, $b) {
return $a->id <=> $b->id;
});
$groups = [];
foreach ($input as $item) {
// Create new group array
if (!array_key_exists($item->position, $groups)) {
$groups[$item->position] = [];
}
// Add item to group
$groups[$item->position][] = $item;
}
// Sort groups by position
ksort($groups);
// Merge groups 1 item at a time
function merge_groups(&$groups, &$target) {
foreach ($groups as $position => $group) {
if (!empty($group)) {
$target[] = array_shift($groups[$position]);
} else {
unset($groups[$position]);
}
}
if (!empty($groups)) {
merge_groups($groups, $target);
}
}
// Our final result array
$ouput = [];
merge_groups($groups, $ouput);
var_dump($ouput);
Tested in PHP 7.
Solution with simple loops. Foreach searches for a specific position and then increases the position. The number of positions can be more than 3. Positions like 123 123 23 are also possible.
$input = [
(object)[
"id" => 1,
"name" => "ASDAS",
"position" => 1,
],
(object)[
"id" => 2,
"name" => "ASDAS",
"position" => 1,
],
(object)[
"id" => 3,
"name" => "ASDAS",
"position" => 3,
],
(object)[
"id" => 4,
"name" => "ASDAS",
"position" => 2,
],
(object)[
"id" => 5,
"name" => "ASDAS",
"position" => 2,
],
(object)[
"id" => 6,
"name" => "ASDAS",
"position" => 3,
],
(object)[
"id" => 7,
"name" => "ASDAS",
"position" => 2,
],
(object)[
"id" => 8,
"name" => "ASDAS",
"position" => 1,
]
];
$minPos = min(array_column($input, "position"));
$arr = [];
$pos = $minPos;
while(true){
$found = false;
foreach($input as $key => $obj){
if($obj->position == $pos){
$arr[] = $obj;
unset($input[$key]);
++$pos;
$found = true;
}
}
if(empty($input)) break;
$minPos = min(array_column($input, "position"));
if(!$found AND $pos != $minPos){
$pos = $minPos;
}
}
var_dump($arr);
I have array and first of all I want to differentiate base on site(key) and site is not limited to 1 or 2
And then sum of opening balance and closing balance of site
like all site(888) total_balance = opening_balance + closing_balance
(999) total_balance = opening_balance + closing_balance
"games": [
{
"id": 240,
"user_id": 1,
"site": "888",
"opening_balance": 5,
"closing_balance": 6
},
{
"id": 243,
"user_id": 1,
"site": "999",
"opening_balance": 3,
"closing_balance": 4
},
{
"id": 244,
"user_id": 1,
"site": "888",
"opening_balance": 5,
"closing_balance": 6
},
And want output like
(site => 888, total_balance => 22 , site => 999, total_balance => 7
(it could b string))
And code I tried:
{
$collection = collect(Site::all())->map(function($item , $key){
return $item["name"];
});
$record = Game::whereIn('site',$collection)->get();
dd($record);
/*$bySite = array();
foreach ($record as $key => $item) {
if(!isset($bySite[$item['site']])) {
$bySite[$item['site']] = array();
}
$bySite[$item['site']][$key] = $item;
}*/
}
after this code which I commented output is
but then I don't know how sum of this
{
"888": {
"0": {
"id": 240,
"user_id": 1,
"site": "888",
"opening_balance": 5,
"closing_balance": 6
},
"2": {
"id": 244,
"user_id": 1,
"site": "888",
"opening_balance": 5,
"closing_balance": 6
},
},
"999": {
"1": {
"id": 243,
"user_id": 1,
"site": "999",
"opening_balance": 3,
"closing_balance": 4,
You can achieve this using Laravel Collection.
$games = [
[
"id" => 240,
"user_id" => 1,
"site" => "888",
"opening_balance" => 5,
"closing_balance" => 6
],
[
"id" => 243,
"user_id" => 1,
"site" => "999",
"opening_balance" => 3,
"closing_balance" => 4
],
[
"id" => 244,
"user_id" => 1,
"site" => "888",
"opening_balance" => 5,
"closing_balance" => 6
]
];
$games = collect($games);
$games = $games->groupBy('site')->map(function($game, $key){
return [
'site' => $key,
'total_balance' => $game->sum('opening_balance') + $game->sum('closing_balance'),
];
})->values();
dd($games->toArray());
And the output would be,
array:2 [▼
0 => array:2 [▼
"site" => 888
"total_balance" => 22
]
1 => array:2 [▼
"site" => 999
"total_balance" => 7
]
]
Code Snippet : https://implode.io/5aPGeH
step
1. foreach ($collection)
2. sum the value and store in array like ($collection->sum('opening_balance'), ($collection->sum('closing_balance')
3. then sum the variable
4. stop loop
5. then $final = $final['site'] . " => " . $final['sum'];
Can't seem to find an answer to my doubt, so I decided to post the question and see if someone can help me.
In my application, I have an array of ids which comes from the backend and which is ordered already as I want, for example:
[0] => 23, [1] => 12, [2] => 45, [3] => 21
I then "ask" elasticsearch the information corresponding to each id present in this array, using a terms filter. The problem is the results don't come in the order of the ids I sent, so the results get mixed up, like: [0] => 21, [1] => 45, [2] => 23, [3] => 12
Note that I can't sort in elasticsearch by the sorting that orders the array in the backend.
I also can't order them in php as I'm retrieving paginated results from elasticsearch, so if each oage had 2 results, elasticsearch could give me the info only for [0] => 21, [1] => 45, so I can't even order them with php.
How can I get the results ordered by the input array? Any ideas?
Thanks in advance
Here is one way you can do it, with custom scripted scoring.
First I created some dummy data:
curl -XPUT "http://localhost:9200/test_index"
curl -XPOST "http://localhost:9200/test_index/_bulk " -d'
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 1 } }
{ "name" : "Document 1", "id" : 1 }
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 2 } }
{ "name" : "Document 2", "id" : 2 }
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 3 } }
{ "name" : "Document 3", "id" : 3 }
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 4 } }
{ "name" : "Document 4", "id" : 4 }
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 5 } }
{ "name" : "Document 5", "id" : 5 }
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 6 } }
{ "name" : "Document 6", "id" : 6 }
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 7 } }
{ "name" : "Document 7", "id" : 7 }
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 8 } }
{ "name" : "Document 8", "id" : 8 }
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 9 } }
{ "name" : "Document 9", "id" : 9 }
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 10 } }
{ "name" : "Document 10", "id" : 10 }
'
I used an "id" field even though it's redundant, since the "_id" field gets converted to a string, and the scripting is easier with integers.
You can get back a specific set of docs by id with the ids filter:
curl -XPOST "http://localhost:9200/test_index/_search" -d'
{
"filter": {
"ids": {
"type": "docs",
"values": [ 1, 8, 2, 5 ]
}
}
}'
but these will not necessarily be in the order you want them. Using script based scoring, you can define your own ordering based on document ids.
Here I pass in a parameter that is a list of objects that relate ids to score. The scoring script simply loops through them until it finds the current document id and returns the predetermined score for that document (or 0 if it isn't listed).
curl -XPOST "http://localhost:9200/test_index/_search" -d'
{
"filter": {
"ids": {
"type": "docs",
"values": [ 1, 8, 2, 5 ]
}
},
"sort" : {
"_script" : {
"script" : "for(i:scoring) { if(doc[\"id\"].value == i.id) return i.score; } return 0;",
"type" : "number",
"params" : {
"scoring" : [
{ "id": 1, "score": 1 },
{ "id": 8, "score": 2 },
{ "id": 2, "score": 3 },
{ "id": 5, "score": 4 }
]
},
"order" : "asc"
}
}
}'
and the documents are returned in the proper order:
{
"took": 11,
"timed_out": false,
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
},
"hits": {
"total": 4,
"max_score": null,
"hits": [
{
"_index": "test_index",
"_type": "docs",
"_id": "1",
"_score": null,
"_source": {
"name": "Document 1",
"id": 1
},
"sort": [
1
]
},
{
"_index": "test_index",
"_type": "docs",
"_id": "8",
"_score": null,
"_source": {
"name": "Document 8",
"id": 8
},
"sort": [
2
]
},
{
"_index": "test_index",
"_type": "docs",
"_id": "2",
"_score": null,
"_source": {
"name": "Document 2",
"id": 2
},
"sort": [
3
]
},
{
"_index": "test_index",
"_type": "docs",
"_id": "5",
"_score": null,
"_source": {
"name": "Document 5",
"id": 5
},
"sort": [
4
]
}
]
}
}
Here is a runnable example: http://sense.qbox.io/gist/01b28e5c038c785f0844abb7c01a71d69a32a2f4