PHP/MongoDB - sort by time - php

I have the following MongoDB object:
{
"_id": ObjectId("50954f0d13f88da4a590e5ff"),
"uname": "Eamorr",
"1": {
"table": "1",
"color": "red",
"time": NumberInt(1351963491),
"niceTime": "2012-11-03T17: 24: 51+00: 00"
},
"3": {
"table": "3",
"color": "green",
"time": NumberInt(1351963567),
"niceTime": "2012-11-03T17: 26: 07+00: 00"
},
"4": {
"table": "4",
"color": "orange",
"time": NumberInt(1351963506),
"niceTime": "2012-11-03T17: 25: 06+00: 00"
}
}
How do I sort this object by 'time'?
I want table 3 to be first, table 4 to be second and table 1 to be last in the list.
I'm really stuck... Please help!
Update:
I should add, that my server returns the following JSON object:
[{
"table": "4",
"color": "orange",
"time": 1351965770,
"niceTime": "2012-11-03T18:02:50+00:00"
}, {
"table": "3",
"color": "red",
"time": 1351964379,
"niceTime": "2012-11-03T17:39:39+00:00"
}, {
"table": "1",
"color": "red",
"time": 1351964997,
"niceTime": "2012-11-03T17:49:57+00:00"
}]
Is it easier to sort this?
Many thanks,

$coll->find($range, $co)->sort(array('time' => -1) );

Got it...
Using the second JSON (above), I did:
function my_sort($a, $b){
if ($a['time'] > $b['time']) {
return -1;
} else if ($a['time'] < $b['time']) {
return 1;
} else {
return 0;
}
}
usort($obj,'my_sort');
echo json_encode($obj);

Related

Is it possible to edit the elements of a json array to accomodate additional data/elements?

I'm retrieving data from a database and pushing it to arrays then use json_encode() to output in json format. I have ended up having the data in this format.
[
{
"category_id": "1",
"category_name": "Construction Materials"
},
{
"items": [
{
"id": "1",
"item_name": "Wire Mesh",
"price": "459",
"image_url": null
},
{
"id": "2",
"item_name": "Cement",
"price": "700",
"image_url": null
},
{
"id": "3",
"item_name": "Barbed Wire",
"price": "3000",
"image_url": null
},
{
"id": "4",
"item_name": "Iron sheet",
"price": "200",
"image_url": null
}
]
},
{
"category_id": "2",
"category_name": "Plumbing"
},
Here is what I want to achieve:
[
{
"category_id": "1",
"category_name": "Construction Materials"
"items": [
{
"id": "1",
"item_name": "Wire Mesh",
"price": "459",
"image_url": null
},
{
"id": "2",
"item_name": "Cement",
"price": "40",
"image_url": null
},
{
"id": "3",
"item_name": "Barbed Wire",
"price": "3000",
"image_url": null
},
{
"id": "4",
"item_name": "Iron sheet",
"price": "200",
"image_url": null
}
]
},
{
"category_id": "2",
"category_name": "Plumbing"
},
How can I achive this in php. Is it possible to edit the contents of the main array? how can I add "items" after "category_name"
Regards..
$array = json_decode($yourJson);
$arrayLength = count($array);
$finalArray = [];
for ($i=0; $i < $arrayLength; $i+=2) {
$finalArray[] = $array[$i] + $array[$i + 1];
}
$backToJson = json_encode($finalArray);
Alternative to Mattijs's answer.
function get_first_property($object) {
$properties = array_keys(get_object_vars($object));
return reset($properties);
}
function object_merge($object1, $object2) {
return (object) array_merge((array) $object1, (array) $object2);
}
// loop through each of the array objects
$previous_first_property = null;
foreach ($array as $i => $object) {
$first_property = get_first_property($object);
// merge if the 1st property is "items", and the previous 1st was "category_id"
if ($first_property == "items" && $previous_first_property == "category_id") {
$array[$i - 1] = object_merge($array[$i - 1], $array[$i]);
unset($array[$i]);
}
$previous_first_property = $first_property;
}

about the json format (jstree, php)

I am trying to make the data format like below. for using jstree module
[{
"id":"1" ,
"parent_id":"0",
"text":"TEST",
"children":[{
"id":"2",
"parent_id":"1",
"text":"TEST1",
"children":[{
"id":"4",
"parent_id":"2",
"text":"TEST1-1"
}, {
"id":"5",
"parent_id":"2",
"text":"TEST1-2"
}, {
"id":"6",
"parent_id":"2",
"text":"TEST1-3"
}]
}, {
"id":"3",
"parent_id":"1",
"text":"TEST2",
"children":[{
"id":"7",
"parent_id":"3",
"text":"TEST2-1"
}, {
"id":"8",
"parent_id":"3",
"text":"TEST2-1"
}, {
"id":"9",
"parent_id":"3",
"text":"TEST2-1"
}]
}]
}]
but.. mine is
[{
"id":"1" ,
"parent_id":"0",
"text":"TEST",
"children":{
"id":"3",
"parent_id":"1",
"text":"\ud14c\uc2a4\ud2b82",
"children":{
"id":"9",
"parent_id":"3",
"text":"\ud14c\uc2a4\ud2b82-3"
}
}
},{
"children":{
"id":"1",
"parent_id":"0",
"text":"TEST1",
"children":{
"id":"3",
"parent_id":"1",
"text":"TEST2",
"children":{
"id":"9",
"parent_id":"3",
"text":"TEST2-3"
}
}
}
},{
"id":"2",
"parent_id":"1",
"text":"TEST1",
"children":{
"id":"6",
"parent_id":"2",
"text":"TEST1-3"
}
},{
"id":"3",
"parent_id":"1",
"text":"TEST2",
"children":{
"id":"9",
"parent_id":"3",
"text":"TEST2-3"
}
},{
"id":"4",
"parent_id":"2",
"text":"TEST1-1"
},{
"id":"5",
"parent_id":"2",
"text":"TEST1-2"
},{
"id":"6",
"parent_id":"2",
"text":"TEST1-3"
},{
"id":"7",
"parent_id":"3",
"text":"TEST2-1"
},{
"id":"8",
"parent_id":"3",
"text":"TEST2-2"
},{
"id":"9",
"parent_id":"3",
"text":"TEST2-3"
}]
I have no idea about the arrays or JSON. Here is the code:
$refs = array();
$list = array();
$sql = "
select id, parent_id, text
from code
where use_yn = 'Y'
$result = mysql_query($sql);
while($data = mysql_fetch_assoc($result)) {
$thisref = &$refs[$data['id']];
$thisref['id'] = $data['id'];
$thisref['parent_id'] = $data['parent_id'];
$thisref['text'] = iconv("euc-kr", "utf-8", $data['text']);
if ($data['id'] == 0) {
$list[ $data['id'] ] = &$thisref;
} else {
$refs[ $data['parent_id'] ]['children'] = &$thisref;
}
}
echo json_encode(array_values($refs));
Can anyone help me?
You are mixing different methods to form json for jsTree.
You either 1) use a multilevel structure using key children - you have that in the beginning of your result json, or 2) you use a one-level structure, don't use children keyword, just specify the parent node. I suggest you use the second way.
Instead of parent_id you should use simply parent.
Your output json contains duplicate entries with ids '1', '3', '9'. It is no good.
For root node use # as id.
To me your target json should look like below. To get it the correct php iteration snippet would probably look closer to as below, but you will have to specifically filter out duplicate entries which is not in the code yet.
Then you will get the expected result as in this demo - Fiddle.
while($data = mysql_fetch_assoc($result)) {
$thisref = &$refs[$data['id']];
$thisref['id'] = $data['id'] == 0 ? '#' : $data['id']; // if id is 0 , it's a root node, replace with '#'
$thisref['parent'] = $data['parent_id'] == 0 ? '#' : $data['parent_id'];// if parent id is 0, it's a root node, replace with '#'
$thisref['text'] = iconv("euc-kr", "utf-8", $data['text']);
$refs[] = &$thisref;
}
Correct json:
var data = [{
"id": "1",
"parent": "#",
"text": "TEST"
}, {
"id": "3",
"parent": "1",
"text": "테스트2"
}, {
"id": "9",
"parent": "3",
"text": "테스트2-3"
}, {
"id": "2",
"parent": "1",
"text": "TEST1"
}, {
"id": "6",
"parent": "2",
"text": "TEST1-3"
}, {
"id": "4",
"parent": "2",
"text": "TEST1-1"
}, {
"id": "5",
"parent": "2",
"text": "TEST1-2"
}, {
"id": "6",
"parent": "2",
"text": "TEST1-3"
}, {
"id": "7",
"parent": "3",
"text": "TEST2-1"
}, {
"id": "8",
"parent": "3",
"text": "TEST2-2"
}]
Also check docs at jsTree json reference

How to merge JSON two indexes and then Parse information

I am trying to iterate both index of JSON(Players and Buildings), so that i can a get new result in jQuery
I have two index of JSON one having information of Players and second index having information of Building related Player.
I want to Parse it so that i can get Player and its building name.
My Actual JSON result
{
"Players": [
{
"id": "35",
"building_id": "8",
"room_num": "101",
},
{
"id": "36",
"building_id": "9",
"room_num": "102",
},
{
"id": "37",
"building_id": "10",
"room_num": "103",
},
{
"id": "38",
"building_id": "11",
"room_num": "104",
}
],
"Buildings": [
{
"id": "8",
"name": "ABC"
},
{
"id": "9",
"name": "DEF"
},
{
"id": "10",
"name": "GHI"
},
{
"id": "11",
"name": "JKL"
}
]
}
Need this
"information": [
{
"player_id": "35",
"Buildings_name": "ABC"
},
{
"player_id": "36",
"Buildings_name": "DEF"
},
{
"player_id": "37",
"Buildings_name": "GHI"
},
{
"player_id": "38",
"Buildings_name": "JKL"
}
]
}
Here you go, this go for each player and check if there are buildings and will map them to new structure. This will not filter values for buildings that do not have mapping to players, and will not include the buildings with no players.
var x = {
"Players": [
{
"id": "35",
"building_id": "8",
"room_num": "101",
},
{
"id": "36",
"building_id": "9",
"room_num": "102",
},
{
"id": "37",
"building_id": "10",
"room_num": "103",
},
{
"id": "38",
"building_id": "11",
"room_num": "104",
}
],
"Buildings": [
{
"id": "8",
"name": "ABC"
},
{
"id": "9",
"name": "DEF"
},
{
"id": "10",
"name": "GHI"
},
{
"id": "11",
"name": "JKL"
}
]
};
var res = $.map(x.Players, function(item) {
return {
player_id: item.id,
building_name: $.grep(x.Buildings, function(i) {
return i.id == item.building_id
}).length != 0 ? $.grep(x.Buildings, function(i) {
return i.id == item.building_id
})[0].name : undefined
}
})
and if you want to filter values that do not have relationships e.g INNER join
var resInnerJoin = $.grep($.map(x.Players, function(item) {
return {
player_id: item.id,
building_name: $.grep(x.Buildings, function(i) {
return i.id == item.building_id
}).length != 0 ? $.grep(x.Buildings, function(i) {
return i.id == item.building_id
})[0].name : undefined
}
}), function(it) {
return it.building_name != undefined
})
If you need it in PHP :
$json = '{...}';
// create and PHP array with you json data.
$array = json_decode($json, true);
// make an array with buildings informations and with building id as key
$buildings = array();
foreach( $array['Buildings'] as $b ) $buildings[$b['id']] = $b;
$informations = array();
for ( $i = 0 ; $i < count($array['Players']) ; $i++ )
{
$informations[$i] = array(
'player_id' => $array['Players'][$i]['id'],
'Buildings_name' => $buildings[$array['Players'][$i]['building_id']]['name']
);
}
$informations = json_encode($informations);
var_dump($informations);

PHP Troubles with converting from JSON to stdClass, making changes, and then converting back to JSON

So, in the very beginning, before the send_sms.php is loaded, I have this Json stored in a database:
{
"chats": {
"chat": [{
"id": "1",
"name": "Ethan Wilberforce",
"messages": {
"message": [{
"id": "1",
"name": "Ethan Wilberforce",
"text": "Hello how are you doing",
"time": "4:41"
}, {
"id": "2",
"name": "Qasim Iqbal",
"text": "Not bad. How about you?",
"time": "4:42"
}, {
"id": "3",
"name": "Ethan Wilberforce",
"text": "I'm not too bad myself.",
"time": "4:43"
}]
}
}, {
"id": "2",
"name": "Geoff Vahaaho",
"messages": {
"message": [{
"id": "1",
"name": "Geoff Vahaaho",
"text": "Hello how are you doing",
"time": "4:41"
}, {
"id": "2",
"name": "Qasim Iqbal",
"text": "Not bad. How about you?",
"time": "4:42"
}, {
"id": "3",
"name": "Geoff Vahaaho",
"text": "I'm not too bad myself.",
"time": "4:43"
}, {
"id": "4",
"name": "Qasim Iqbal",
"text": "Nice.",
"time": "4:43"
}]
}
}]
}
}
The Json is completely valid, no errors. It is storing two chats, with messages in them.
Now, here is the PHP code that alters the Json:
$data = $user->data;
$parsed_data = json_decode($data);
...
for($i = 0, $size = sizeof($parsed_data->chats->chat); $i < $size; ++$i) {
if($parsed_data->chats->chat[$i]->name == $to) {
$found = true;
$parsed_data->chats->chat[$i]->messages->message[sizeof($parsed_data->chats->chat[$i]->messages->message)] = new stdClass;
$parsed_data->chats->chat[$i]->messages->message[sizeof($parsed_data->chats->chat[$i]->messages->message)]->id = sizeof($parsed_data->chats->chat[$i]->messages->message);
$parsed_data->chats->chat[$i]->messages->message[sizeof($parsed_data->chats->chat[$i]->messages->message)]->name = $user->name;
$parsed_data->chats->chat[$i]->messages->message[sizeof($parsed_data->chats->chat[$i]->messages->message)]->text = $message;
$parsed_data->chats->chat[$i]->messages->message[sizeof($parsed_data->chats->chat[$i]->messages->message)]->time = $time;
echo "done. ";
break;
}
}
What I intend this to do is, to add another stdClass object in the "message" array of the chat. So I basically do just that, hoping it will work.
Now, it works, kind of, but here is the new Json after we json_encode it:
{
"chats": {
"chat": [{
"id": "1",
"name": "Ethan Wilberforce",
"messages": {
"message": [{
"id": "1",
"name": "Ethan Wilberforce",
"text": "Hello how are you doing",
"time": "4:41"
}, {
"id": "2",
"name": "Qasim Iqbal",
"text": "Not bad. How about you?",
"time": "4:42"
}, {
"id": "3",
"name": "Ethan Wilberforce",
"text": "I'm not too bad myself.",
"time": "4:43"
}, {}, {
"id": 4
}, {
"name": "Qasim Iqbal"
}, {
"text": "Hello i am testing"
}, {
"time": 1326066200
}]
}
}, {
"id": "2",
"name": "Geoff Vahaaho",
"messages": {
"message": [{
"id": "1",
"name": "Geoff Vahaaho",
"text": "Hello how are you doing",
"time": "4:41"
}, {
"id": "2",
"name": "Qasim Iqbal",
"text": "Not bad. How about you?",
"time": "4:42"
}, {
"id": "3",
"name": "Geoff Vahaaho",
"text": "I'm not too bad myself.",
"time": "4:43"
}, {
"id": "4",
"name": "Qasim Iqbal",
"text": "Nice.",
"time": "4:43"
}]
}
}]
}
}
You will notice it was indeed added in the "Ethan Wilberforce" chat, but each string in the stdClass was converted to its own array item in the "message" array. How could I fix this problem? Many thanks.
Your problem is this:
$parsed_data->chats->chat[$i]->messages->message[sizeof($parsed_data->chats->chat[$i]->messages->message)] = new stdClass;
$parsed_data->chats->chat[$i]->messages->message[sizeof($parsed_data->chats->chat[$i]->messages->message)]->id = sizeof($parsed_data->chats->chat[$i]->messages->message);
It basically amounts to:
$array[$last] = new stdClass();
$array[$last+1] = "id";
$array[$last+2] = "name";
You keep appending new arrays/objects, because you use sizeof(...) which always becomes one larger than the previous line. It's not the last index, but the size. Which is $lastindex+1.
What you should be doing anyway, is not using an object, but just appending an array, and with all its attributes at once:
$parsed_data->chats->chat[$i]->messages->message[] = array(
"id" => ...,
"name" => ...,
"time" => ...,
);
When you encode that associative array back into JSON it will also become a normal {...} JSON object group.

regular and between nested array mongodb

I have a document like this in mongodb
{
"_id": {
"$oid": "56b7451fa91b80e2078b4567"
},
"number": "222",
"value": "hello",
"name": "James",
"username": "mahsa",
"lessons": [
{
"id": "2",
"time": "2016-02-11 07:15:00",
"term": "3"
"marks": [
{
"id": "4",
"value": "10",
},
{
"id": "5",
"value": "9",
}
]
},
{
"id": "3",
"time": "2016-02-11 07:45:00",
"term": "4"
}
]
}
I'd like to push a nested array only when my variables are exactly this: array('number'=>'222','lessons.id'=>'2','lessons.term'=>'3')
after
"id": "2", "time": "2016-02-11 07:15:00", "term": "3"
, but when I use
array('number'=>'222','lessons.id'=>'2','lessons.term'=>'4')
or
array('number'=>'222','lessons.id'=>'3','lessons.term'=>'3')
has a similar result
my code is
$this->collection->update(
array('number'=>'222','lessons.id'=>'2','lessons.term'=>'3'),
array('$push'=>array(
'lessons.$.marks'=> array(
array('id'=>'444','value'=>'100'),
array('id'=>'555','value'=>'90')
))));
Can I solve this problem or mongo can't support somethings like this?
Mongo does support it, you just need to use the proper syntax:
{
'number': '222',
'lessons': {
'$elemMatch': {
'id' : '3',
'term': '3'
}
}
}, {
'$push': {
'lessons.$.marks': {
'$each': [{
'id': '444',
'value': '100'
}, {
'id': '555',
'value': '90'
}]
}
}
}
Here is probably what you need in PHP:
$this->collection->update(
array('number'=>'222',
array('$elemMatch'=>array('lessons.id'=>'2','lessons.term'=>'3')),
array('$push'=>array(
'lessons.$.marks'=> array(
'$each'=>array(
array('id'=>'444','value'=>'100'),
array('id'=>'555','value'=>'90')
)))));

Categories