I would like to get the distinct code_y values, and I use below code, the output is equal to select distinct code_y from table_x,
$res = $db_x->command (
array(
"aggregate" => "table_x",
"pipeline" =>
array(
array( '$group' => array( "_id" => ['id' =>'$code_y', 'name' => '$code_x', 'color' => '$color']))),
"cursor" => ['batchSize' => 200]
)
);
I got results as below, I don't need [_id] => Array, just id, name and color, How to separate array from nested arrays with MongoDB and PHP aggregate? Or how to put [_id] => Array together with id, name and color? as in my front-end htmls pages, I got [object] [Object] because of those nested arrays.
[0] => Array
(
[_id] => Array
(
[id] => a1
[name] => bbb
[color] => blue
)
)
[1] => Array
(
[_id] => Array
(
[id] => a2
[name] => aaa
[color] => blue
)
)
[2] => Array
(
[_id] => Array
(
[id] => a3
[name] => abc
[color] =>red
)
)
What I want is as below:
[0] => Array
(
[id] => a1
[name] => bbb
[color] => blue
)
[1] => Array
(
[id] => a2
[name] => aaa
[color] => blue
)
[2] => Array
(
[id] => a3
[name] => abc
[color] =>red
)
What you need is a another stage after the group.
You could either use project and list each field:
array( '$project' => array(
"id" => '$_id.id',
"name" => '$_id.name',
"color" => '$_id.color'
))
or $replaceRoot to grab them all:
array( '$replaceRoot' => array( "newRoot" => '$_id' ))
Related
I break my head how to do this.I need to connect three data sets from different data tables. One ID has a key to the second, the second to the third (ID -> if UF_DRIVER has ID -> NAME1 or ID -> if UF_DRIVER has ID -> NAME2)
There are three arrays: $arItems and $arProps1 and $arProps2
Elements of the first array $arItems:
Array([0] => 2707) Array([0] => 2708)
Elements of the second array $arProps1:
Array
(
[0] => Array
(
[ID] => 2707
[UF_VISITOR] => 1909
[UF_DRIVER] =>
)
[0] => Array
(
[ID] => 2708
[UF_VISITOR] =>
[UF_DRIVER] => 1910
)
)
Elements of the third array $arProps2:
Array
(
[0] => Array
(
[ID] => 1909
[UF_FIRSTNAME] => NAME1
)
[1] => Array
(
[ID] => 1910
[UF_FIRSTNAME] => NAME2
)
[2] => Array
(
[ID] => 2015
[UF_FIRSTNAME] => NAME3
)
)
How to merge these array elements into one array element ?:
Array([0] => 2707 => Array(
[0] => Array(
[ID] => 2707
[UF_VISITOR] => 1909
[UF_DRIVER] =>
) => Array ([0] => Array([ID] => 1909
[UF_FIRSTNAME] => NAME1
))
Array([0] => 2708 => Array(
[0] => Array(
[ID] => 2708
[UF_VISITOR] =>
[UF_DRIVER] => 1910
) => Array ([0] => Array([ID] => 1910
[UF_FIRSTNAME] => NAME2
))
I tries to array_merge in php but resultant array is not correct
1. Array ( [id] => 12 [name] => Popular )
2. Array ( [0] => Array ( [id] => 8 [name] => Flowers ) [1] => Array ( [id] => 10 [name] => Chocolates ) [2] => Array ( [id] => 11 [name] => Sweets and Dry Fruits ) )
Resultant Array
Array ( [id] => 12 [name] => Popular [0] => Array ( [id] => 8 [name] => Flowers ) [1] => Array ( [id] => 10 [name] => Chocolates ) [2] => Array ( [id] => 11 [name] => Sweets and Dry Fruits ) )
If you just want to add the new data in the same format as the existing data then use [] rather than array_merge().
$array1 = array( 'id' => 12, 'name' => 'Popular');
$array2 = array(array( 'id' => 8, 'name' => 'Flowers'),
array( 'id' => 10, 'name' => 'Chocolates'),
array( 'id' => 11, 'name' => 'Sweets and Dry Fruits')
);
$array2[] = $array1;
print_r($array2);
outputs...
Array
(
[0] => Array
(
[id] => 8
[name] => Flowers
)
[1] => Array
(
[id] => 10
[name] => Chocolates
)
[2] => Array
(
[id] => 11
[name] => Sweets and Dry Fruits
)
[3] => Array
(
[id] => 12
[name] => Popular
)
)
If you want the data to be at the front, then you need to create an array of that data and then use array_merge()...
$array3 = array_merge(array($array1), $array2);
print_r( $array3);
In my app, I have the following Models and relationships:
ActiveMember belongsTo Team
ActiveMember belongsTo Rank
ActiveMember hasMany ContactInfo
ContactInfo belongsTo ContactType
In my controller, I am them doing a contained find as so;
$this->Team->contain(array(
'ActiveMember' => array (
'fields' => array('id','surname','firstname'),
'Rank' => array(
'fields' => array('id','display','position')) ,
'ContactInfo' => array (
'ContactType',
'conditions' => 'contact_type_id IN (1, 2, 3, 4)'
)
)
)
);
$Teams = $this->Team->find('all', array('conditions' => 'Team.active = 1 AND Team.display_order<99'));
This then returns an array like this:
Array
(
[0] => Array
(
[Team] => Array
(
[id] => 3
[name] => Command
[display_order] => 1
[active] => 1
)
[ActiveMember] => Array
(
[0] => Array
(
[id] => 1
[surname] => Bloggs
[firstname] => Joe
[rank_id] => 1
[team_id] => 3
[Rank] => Array
(
[id] => 1
[display] => Commander
[position] => 1
)
[ContactInfo] => Array
(
[0] => Array
(
[id] => 2
[member_id] => 1
[contact_type_id] => 1
[info] => 1234 5678
[ContactType] => Array
(
[id] => 1
[name] => Home Phone
[format] => #### ####
)
)
)
)
[1] => Array
(
[id] => 3
[surname] => Smith
[firstname] => Jane
[rank_id] => 2
[team_id] => 3
[Rank] => Array
(
[id] => 2
[display] => Dep Comm
[position] => 10
)
[ContactInfo] => Array
(
)
)
)
)
[1] => Array
(
[Team] => Array
(
[id] => 1
[name] => Support
[display_order] => 2
[active] => 1
)
[ActiveMember] => Array
(
[0] => Array
(
[id] => 124
[surname] => Johnson
[firstname] => John
[rank_id] => 6
[team_id] => 1
[Rank] => Array
(
[id] => 6
[display] => Member
[position] => 50
)
[ContactInfo] => Array
(
)
)
And then I want to sort the result as per 'ORDER BY Team.display_order, Team.Member.Rank.position, Team.Member.surname, Team.Member.firstname'
Given that I can't do this complex sort in the query without doing adhoc joins, I thought I could use Set::sort, called four times to sort the order.
$Teams = Set::sort($Teams,'{n}.ActiveMember.{n}.surname','asc');
$Teams = Set::sort($Teams,'{n}.ActiveMember.{n}.firstname','asc');
$Teams = Set::sort($Teams,'{n}.ActiveMember.{n}.Rank.position','asc');
$Teams = Set::sort($Teams,'{n}.Team.display_order','asc');
However, despite the Set path of the first three lines returning correct values if I do a Set::extract, they do not have any effect on the array order (either when called as a group, or as the only sort). The final line works.
Can someone please advise where my mistake is, or another way to achieve the same result?
Updated: I have two separate arrays which hold some data returned from search() function of SolrPhpClient. The arrays contain data in form of Apache_Sole_Document objects. These objects in turn contain the actual fields and values. I merge these two arrays to get a single array holding all items using array_merge() of PHP
The array will have some duplicate items which needs to be removed.
I am not sure how to achieve it in this structure.
The array structure is as such:
Array ( [0] => Apache_Solr_Document Object (
[_documentBoost:protected] =>
[_fields:protected] => Array ( [id] => 111 [name] => ABCD )
[_fieldBoosts:protected] => Array ( [id] => [name] => )
)
[1] => Apache_Solr_Document Object (
[_documentBoost:protected] =>
[_fields:protected] => Array ( [id] => 222 [name] => DEFG )
[_fieldBoosts:protected] => Array ( [id] => [name] => )
)
[2] => Apache_Solr_Document Object (
[_documentBoost:protected] =>
[_fields:protected] => Array ( [id] => 333 [name] => LMNO )
[_fieldBoosts:protected] => Array ( [id] => [name] => )
)
[3] => Apache_Solr_Document Object (
[_documentBoost:protected] =>
[_fields:protected] => Array ( [id] => 111 [name] => ABCD )
[_fieldBoosts:protected] => Array ( [id] => [name] => )
)
[4] => Apache_Solr_Document Object (
[_documentBoost:protected] =>
[_fields:protected] => Array ( [id] => 444 [name] => PQRS )
[_fieldBoosts:protected] => Array ( [id] => [name] => )
)
[5] => Apache_Solr_Document Object (
[_documentBoost:protected] =>
[_fields:protected] => Array ( [id] => 222 [name] => DEFG )
[_fieldBoosts:protected] => Array ( [id] => [name] => )
)
)
As you can see there is a [id] field and a [name] field.
I would like to remove duplicates from the array comparing the [id] field.
The final array after removing duplicates should look like this:
Array ( [0] => Apache_Solr_Document Object (
[_documentBoost:protected] =>
[_fields:protected] => Array ( [id] => 111 [name] => ABCD )
[_fieldBoosts:protected] => Array ( [id] => [name] => )
)
[1] => Apache_Solr_Document Object (
[_documentBoost:protected] =>
[_fields:protected] => Array ( [id] => 222 [name] => DEFG )
[_fieldBoosts:protected] => Array ( [id] => [name] => )
)
[2] => Apache_Solr_Document Object (
[_documentBoost:protected] =>
[_fields:protected] => Array ( [id] => 333 [name] => LMNO )
[_fieldBoosts:protected] => Array ( [id] => [name] => )
)
[3] => Apache_Solr_Document Object (
[_documentBoost:protected] =>
[_fields:protected] => Array ( [id] => 444 [name] => PQRS )
[_fieldBoosts:protected] => Array ( [id] => [name] => )
)
)
How can I achieve this? somebody please help!
I guess you could iterate over the array and remove the duplicates, but that doesn't seem like a neat solution to me.
I'm not familiar with the SolrPhpClient, but Solr does support grouping on fields. You can group on the id by adding this part to your request:
group=true&group.field=id
The documents returned will be grouped on the id. For more details check this page.
Update:
I looked at the SolrPhpClient documentation and see that you can add additional parameters to your request like this:
$additionalParameters = array(
'fq' => 'a filtering query',
'facet' => 'true',
'facet.field' => array(
'field_1',
'field_2'
)
);
$results = $solr->search($query, $start, $rows, $additionalParameters);
I assume you can add the grouping parameters to this:
$additionalParameters = array(
'group' => 'true',
'group.field' => 'id'
)
);
$results = $solr->search($query, $start, $rows, $additionalParameters);
For more details on this, check this page
Array
(
[12] => Array
(
[id] => 12
[name] => Car
[children] => Array
(
[0] => Array
(
[id] => 14
[name] => Volvo
)
[1] => Array
(
[id] => 15
[name] => Mercedes-Benz
)
)
)
[13] => Array
(
[id] => 13
[name] => Manga
[children] => Array
(
[0] => Array
(
[id] => 16
[name] => Naruto
)
[1] => Array
(
[id] => 17
[name] => Hunter X Hunter
)
)
)
[18] => Array
(
[id] => 18
[name] => aa
[children] => Array
(
)
)
)
Guys I want to sort the values of this array, i want to sort it by key and the key is 'name'. This should sort the first level and the second level thru key 'name'.
This array i put in print_r() so it looks like this. The array is not fix so i can add in the future.
So after sorting the final value of the array is...
Array
(
[18] => Array
(
[id] => 18
[name] => aa
[children] => Array
(
)
)
[12] => Array
(
[id] => 12
[name] => Car
[children] => Array
(
[0] => Array
(
[id] => 15
[name] => Mercedes-Benz
)
[1] => Array
(
[id] => 14
[name] => Volvo
)
)
)
[13] => Array
(
[id] => 13
[name] => Manga
[children] => Array
(
[0] => Array
(
[id] => 17
[name] => Hunter X Hunter
)
[1] => Array
(
[id] => 16
[name] => Naruto
)
)
)
)
And this is the array in code.
$categories = array(
12 =>
array('id' =>12,
'name' => 'Car',
'children' =>
array(
array('id' => 14,
'name' => 'volvo'
)
),
array(
array('id' => 15,
'name' => 'Mercedez-Benz'
)
)
),
13 =>
array('id' =>13,
'name' => 'Manga',
'children' =>
array(
array('id' => 16,
'name' => 'Naruto'
)
),
array(
array('id' => 17,
'name' => 'Hunter X Hunter'
)
)
),
18=>
array('id' => 18,
'name'=> 'aa',
'children' => array())
);
echo "<pre>";
print_r($categories);
the 'name' is not your real 'Key', just saying, because 'key' in Php normally means the name of your array, like '18' and '12' in your array and so on, like this:
<?php
$fruits = array("d"=>"lemon", "a"=>"orange", "b"=>"banana", "c"=>"apple");
ksort($fruits);
foreach ($fruits as $key => $val) {
echo "$key = $val\n";
}
?>
in this example, the result will be:
a = orange
b = banana
c = apple
d = lemon
anyway to answer your question on how to sort it on 'name', use 'usort':
function cmp($a, $b) {
return $a['name'] - $b['name'];
}
usort($arr,"cmp");
check out the following link for further information:
How do I sort a PHP array by an element nested inside?
if using php 5.3+ you can use closures in your code and sort like this
usort($categories,function($a,$b){
return $a['name'] - $b['name']
}
So,
I'm going to try and explain it better to you
your array is big, yes, but you want to sort only on the key value '[name]'.
In my test I used the array you provided:
$categories = array(
12 =>
array('id' =>12,
'name' => 'Car',
'children' =>
array(
array('id' => 14,
'name' => 'volvo'
)
),
array(
array('id' => 15,
'name' => 'Mercedez-Benz'
)
)
),
13 =>
array('id' =>13,
'name' => 'Manga',
'children' =>
array(
array('id' => 16,
'name' => 'Naruto'
)
),
array(
array('id' => 17,
'name' => 'Hunter X Hunter'
)
)
),
18=>
array('id' => 18,
'name'=> 'aa',
'children' => array())
);
if the array is declared, you can add the usort like this:
usort($categories,"sortByName");
the first element in the above ($categories), is your array, the second element will provide the name of a function, in this case 'sortByName'.
after that, you just add a function into your code (it doesn't really matter where you put it, even if it's at the bottom of the page):
function sortByName($categories, $b) {
return strcasecmp($categories["name"], $b["name"]);
}
Basically what this function does, is compairing your array with ...your array :) so it can sort it alfabetically by name- like you want it.
sthe 'strcasecmp' is to compare your strings against eachother to sort it. not that this is case non sensitive (strcmp will be case sensitive too). I assume you don't want it to check on uppercase and so on too, otherwise the result won't be what you wanted.
when you added that code, you can just print your array again:
echo "<pre>";
print_r($categories);
your result will be:
Array
(
[0] => Array
(
[id] => 18
[name] => aa
[children] => Array
(
)
)
[1] => Array
(
[id] => 12
[name] => Car
[children] => Array
(
[0] => Array
(
[id] => 14
[name] => volvo
)
)
[0] => Array
(
[0] => Array
(
[id] => 15
[name] => Mercedez-Benz
)
)
)
[2] => Array
(
[id] => 13
[name] => Manga
[children] => Array
(
[0] => Array
(
[id] => 16
[name] => Naruto
)
)
[0] => Array
(
[0] => Array
(
[id] => 17
[name] => Hunter X Hunter
)
)
)
I hope this is what you wanted. :-)