Array
(
[Site] => Array
(
[id] => 1
[parent_id] => 0
[title] => test
[url] => http://www.test.com
[slug] => www_test_com
[keywords] => cpc,seo
[language_id] => 1
)
[SiteMeta] => Array
(
[0] => Array
(
[id] => 1
[site_id] => 1
[key] => pagerank
[value] => 5
[created] => 2010-08-03 00:00:00
)
)
)
By using cakephp, I debug my find('all') and returned me above array. I can sort Site field values by order value inside find function how I am able to order also with SiteMeta values
Any ideas?
Thanks
I'd do this in the Model as part of the association.
$hasMany = array('SiteMeta'=>array('order'=>array('SiteMeta.value'=>'asc')))
You won't have to repeat yourself anywhere then.
you can use a default query with a order condition like this:
$result = $this->Site->find('all', array(
'order'=>array('SiteMeta.value DESC' , 'Site.value DESC'),
'recursive'=>1));
Obviously you can put a condition inside the array to retrieve your right result
I would do it this way (as shown in the Docs)
$result = $this->Site
->find()
->contain([
'SiteMeta' => [
'sort' => ['SiteMeta.pagerank' => 'ASC']
]
]);
Related
I have this request to elastic service.
Url callback is:
GET
/es-main/Project,ProjectStage,Task,TaskComment,TicketComment,Client,User,Attachment/_search
How to add Sort improvement requirements that the results were in sequence as they are embedded in the URL + score? Now alphabetically by type. Example first is type Project, second is ProjectStage, etc...
Thanks all for answers...
GET /es-main/Project,ProjectStage,Task,TaskComment,TicketComment,Client,User,Attachment/_search
Array
(
[query] => Array
(
[query_string] => Array
(
[query] => *a*
[analyzer] => hunspell_cs
[fields] => Array
(
[0] => name
[1] => description
[2] => tags.name
[3] => text
[4] => email
[5] => filename
)
)
)
[from] => 0
[size] => 10
[sort] => Array
(
[_type] => ASC
[_score] => DESC
)
[aggs] => Array
(
[CountByType] => Array
(
[terms] => Array
(
[field] => _type
)
)
)
)
Okey, i have added in document _is_Project = 1, _is_ProjectStage = ,_is_Task = 1, etc...
and set ordering to:
order: {
'_is_Project': {'unmapped_type': 'long'}, // first
'_is_ProjectStage': {'unmapped_type': 'long'}, // second
'_is_Task': {'unmapped_type': 'long'}, // third - etc...
'_score': 'DESC'
}
Following is the Banking MySQL table structure:
id | name | type
1 | abc | xyz
2 | jkl | xyz
3 | efg | pql
Right now the records are displayed in the following format:
Array
(
[0] => Array
(
[Banking] => Array
(
[id] => 1
[name] => abc
[type] => xyz
)
)
[1] => Array
(
[Banking] => Array
(
[id] => 2
[name] => jkl
[type] => xyz
)
)
[2] => Array
(
[Banking] => Array
(
[id] => 3
[name] => efg
[type] => pql
)
)
)
I need to GroupBy fields according to type field and display all records. Following is the desired structure:
Array
(
[xyz] => Array
(
[0] => Array
(
[id] => 1
[name] => abc
)
[1] => Array
(
[id] => 2
[name] => jkl
)
)
[pql] => Array
(
[0] => Array
(
[id] => 2
[name] => efg
[type] => xyz
)
)
)
I tried Grouping it the following way but didn't work since GroupBy shows only one record per type.
$bankList = $this -> Banking -> find('all', array(
'order' => 'Banking.name asc',
'fields' => array(
'Banking.id',
'Banking.name',
'Banking.type'
),
'group' => array('Banking.type')
));
Though I achieved the result customizing $bankList:
foreach ($bankList as $b) {
if (!in_array($b['Banking']['type'], $type)) {
$type[] = $b['Banking']['type'];
}
$bList[$b['Banking']['type']][] = array(
'name' => $b['Banking']['name'],
'id' => $b['Banking']['id']
);
}
but wondering if its possible with a Query only?
I tried Grouping it the following way but didn't work since GroupBy
shows only one record per type.
You might want to learn SQL first, because this is the expected behaviour of GROUP BY, see What does group by do exactly ?
The resulting array structure you get is the standard CakePHP structure and has nothing at all to do with the SQL itself. It is just how CakePHP formats them.
Use the Model::afterFind() callback to modify the result as you need. Create a new method like transformResult() and pass your data through it in afterFind().
You can achieve the desired structure by manipulating data after you fetched it from a database. In CakePHP you can use a groupBy method:
$bankList = $this -> Banking -> find('all', array(
'order' => 'Banking.name asc',
'fields' => array(
'Banking.id',
'Banking.name',
'Banking.type'
)
)) -> groupBy('type');
Please note, that it has nothing to do with SQL queries! It is just a convenient way to do same data restructuring as your code.
I have looked through containable component and other questions here, but doesn't look like that can help me.
Basically, I have paginate set to 1, which returns me something just like
Array
(
[0] => Array
(
[ModelName1] => Array
(
[id] => 83
[parent_id] => null
[field1] => value1
)
[AssociatedModelName1] => Array
(
[id] => 1
[field1] => value1
)
[children] => Array
(
[0] => Array
(
[ModelName] => Array
(
[id] => 42
[parent_id] => 83
[field1] => value1
[field2] => value2
[field3] => value3
)
[AssociatedModelName] => Array
(
[id] => 2
[field1] => value1
[field2] => value2
[field3] => value3
)
I am able to limit the output of ModelName1 and AssociatedModelName1 's field by adding
$fields => array("ModelName1.field1")
to the setting array. In fact I pass this to the "column" of the DataTable Plugin's component initialization, but it should be the same.
However, since there are SO MANY CHILDREN, and each children contains a lot of fields, I would like to get only the "field2" of each children.
How can I achieve that? If I specify "Children.ModelName1", I get a SQL1054 error, which is column not found.
Any clue?
You must use a conditional array in one way or another:
$this->paginate['Model'] = array(
'contain' => array(
'ChildModel' => array(
'fields' => array('ChildModel.field1', 'Childmodel.field2'),
'ChildChildModel' => array(
'fields' => array('ChildChildModel.field1', 'ChildChildModel.field2'),
)
)
)
);
I have the models User, Post, Comment and Tag.
User creates Post.
Posts can have multiple Comment and Tag.
Each model has it's own table, so there are tables 'posts', 'comments' and 'tags'. Comments have a foreign key called 'post_id', while Tags have a many_to_many relation table called 'post_tags', in which there are two fields: 'post_id' and 'tag_id'.
I want to get a nested array like below:
Which MySQL queries should I run?
I suppose I need to alter the result with PHP to get my nested array. How?
Thanks a lot for your help :-)
[0] => Array
(
[Post] => Array
(
[id] => 1
[title] => First article
[content] => aaa
[created] => 2008-05-18 00:00:00
)
[Comment] => Array
(
[0] => Array
(
[id] => 1
[post_id] => 1
[author] => Daniel
[email] => dan#example.com
[website] => http://example.com
[comment] => First comment
[created] => 2008-05-18 00:00:00
)
[1] => Array
(
[id] => 2
[post_id] => 1
[author] => Sam
[email] => sam#example.net
[website] => http://example.net
[comment] => Second comment
[created] => 2008-05-18 00:00:00
)
)
[Tag] => Array
(
[0] => Array
(
[id] => 1
[name] => Awesome
)
[1] => Array
(
[id] => 2
[name] => Baking
)
)
)
[1] => Array
(
[Post] => Array
(...
You better of doing 3 queries.
first fetch post (, and left join the user if you need it), and store them like:
$list[$row['post_id']]['Post'] = $row;
then fetch all post-comments and store them as
$list[$row['post_id']]['Comment'][$row['comment_id']] = $row;
then fetch all post-tags
$list[$row['post_id']]['Tags'][$row['tag_id']] = $row;
that far more effective than trying to use a single query,
as a single query going to end up sending the same data multiple times
I have used join query which joins three tables employee, places and employee_places.The join query gives me all the results as I have used find('all').But in the view page I just want to show employee name from employee table - place name from place table in a dropdown.
e.g:- emp1-place1,emp2-place2 and so on. Where should I give the fields name in find.
Look at the following code :
$options['joins'] = array(
array('table' => 'employees',
'alias' => 'emp',
'type' => 'inner',
'conditions' => array(
'emp.id = EmployeePlace.employee_id '
)
),
array('table' => 'places',
'alias' => 'pl',
'type' => 'inner',
'conditions' => array(
'pl.id = EmployeePlace.place_id'
)
)
);
$empTables = $this->Bill->EmployeePlace->find('all', $options);
$this->set(compact('empTables'));
The above query results the following array:-
Array
(
[0] => Array
(
[EmployeePlace] => Array
(
[id] => 1
[employee_id] => 1
[place_id] => 1
[Date] => 2011-02-02
)
[Employee] => Array
(
[id] => 1
[image] =>
[firstName] => Andy
[lastName] => Murray
[date_of_joining] => 2010-09-02
[date_of_leaving] => 2011-02-02
[date_of_birth] => 1991-08-10
[gender] => Male
[supervisor] => 0
[designation] => Manager
[user_id] => 0
)
[Place] => Array
(
[id] => 1
[placeName] => table-1
[section_id] => 1
[position] => Left
[seating_capacity] => 4
)
)
)
I just want firstName from employee - placeName from place table in the dropdown. How do I do this using condition in find.
Use containable: http://book.cakephp.org/view/1323/Containable
You will then only be dealing with data that you require.
Loop over the results and build the strings you want. Add the strings to an array indexed against the value you want the selection to return. Pass the array out to the view.
How are you going to handle the values? What do you want to do when a user has made a selection?
OR:
You could create a db view, which is a table that combines data from other tables on the fly. CakePHP can access this as a normal table.