PHP Mongo aggregate match regex - php

Performing a query that simulates a 'like/mysql' searching for teams on the name of the team
Team document structure
{
"_id": 9,
"name": "azerty",
"tag": "dsfds",
"desc": "ggdfgsdfgdfgdf",
"captain": 8,
"coach": 8,
"members": [{
"date_joined": "2016-03-31 15:22:09",
"user_id": 8
}, {
"date_joined": "2016-03-31 19:22:35",
"user_id": 9
}],
"current_invites": [{
"invite_id": 21,
"username": "Nikki",
"user_id": "9",
"status": 1,
"date_invited": "2016-03-31 18:32:40"
}, {
"invite_id": 22,
"username": "Nikki",
"user_id": "9",
"status": 2,
"date_invited": "2016-03-31 18:33:16"
}]
}
PHP Code =
$q = '/.*'.$q.'*./';
$result = $this->coll->aggregate(
array('$match' => array('name' => $q)),
array('$project' => array('name' => 1,'members' => array('$size' => '$members'))));
Feels like I'm going mad not knowing how to fix this.
Have used regex before after migrating to mongo but not with the combination of agg-match.

in my case i am finding the aggregated result in which you can not set the where clause so use the aggregated functions like $sort $unwind $orderby and so on i am using the all of the above mention and have the problem with the like stuff to match the string like %str% here my code in which i implement the like using $match with MongoRegex
public function getRecords($table,$where = array(),$like_key = false,$like_value = false,$offset = 1,$limit = 10,$order_column = false,$order_type = false, $isAggregate=false,$pipeline=array()){
$temp = $this->getMongoDb()->where($where);
if($like_key && $like_value){
$temp = $temp->like($like_key,$like_value);
// this like filter is for aggregated result work both on normal get record or by aggregated result
$pipeline[]=array(
'$match' => array( $like_key => new MongoRegex( "/$like_value/i" ) )
);
}
if($order_column && $order_type){
$order_by = array();
$order_by[$order_column] = $order_type;
$temp = $temp->order_by($order_by);
$pipeline[]=array(
'$sort'=>array($order_column => ($order_type =="desc")? -1 : 1)
);
}
I got the solution when I read the following aggregation framework go the aggregation framework
I hope you will get your solution to resolve your issue.

Related

getting relational results from three tables into one nested array

i have googled for solution to my problem but nun helped me.
here i have three tables items, feeds and images. each item has one feed and one or more images.
i have 3 functions. one is to return records from items table the second one receives feeds_id (foreign key in items table) then return records from feeds table. the third function is to return all images related to items_id.
those functions are :
* To get all items in database:
function get_items(){
return $query = Database::getInstance('db')
->table('items')
->columns(
'id',
'items.rowid',
'items.feed_id as feed_id',
'title' )
->findAll();
}
* To get feed data from feeds table :
function get_feeds($id){
return $query = Database::getInstance('db')
->table('feeds')
->eq('id',$id)
->findAll();
}
* To get image data from images table :
function get_images($id){
return $query = Database::getInstance('db')
->table('images')
->columns('items_id','src as image_url',
'title as image_title',
'alt')
->eq('items_id',$id)
->findAll();
}
Then i have the following code to call those function and display the result in jsonformat:
$response['items'] = array();
$response['feeds'] = array();
$response['images'] = array();
foreach ($items = get_items() as $item) {
$response['items'][] = array(
'id' => (int)$item['rowid'],
'feed_id' => (int)$item['feed_id'],
'title' => $item['title'],
);
foreach ($feeds = get_feeds((int)$item['feed_id']) as $feed) {
$response['feeds'][] = array(
'title' => $feed['title'],
'logo_url' => $feed['logo_url'],
'site_url' => $feed['site_url'],
);
}
foreach ($images = get_images($item['id']) as $image) {
$response['images'][] = array(
'id' => $image['items_id'],
'url' => $image['image_url'],
'thumb' => $_SERVER['SERVER_NAME'] . /myServer/images/thumbs/'. 'thumb_'.basename($image['image_url']),
'title' => $image['image_title'],
'alt' => $image['alt']
);
}
}
echo json_encode($response, JSON_PRETTY_PRINT);
so, my expectation is to get json output like:
"items": [
{
"id": ,
"feed_id":
"title":
"feeds": [
{
"title": ,
"logo_url": ,
"site_url": "
}
]
"images": [
{
"id": ,
"url": ",
"thumb":
"title": "",
"alt": ""
},
{
....
}
]
}]
i mean each item array should include nested arrays of its related data coming from get_feeds and get_images functions.
instead of that, i get response like :
//here i select two items from my db
"items": [
{ //first_item
"id": ,
"feed_id":
"title":
},
{ //second_item
"id": ,
"feed_id":
"title":
}
],
"feeds": [
{ // feed data for first item
"title": ,
"logo_url": ,
"site_url": "
},
{ // feed data for second item
"title": ,
"logo_url": ,
"site_url": "
}
],
"images": [
{ // image data for first item
"id": ,
"url": ",
"thumb":
"title": "",
"alt": ""
},
{ // other images data
....
}
]
}]
as you see i am getting output without keeping relation between items, feeds and images, all of them are shown independently.
my queries are fine but i am suspecting error in my foreach statements.
i could fix this issue by joining those tree tables in one query, but i don't want to do that because i need to do validation and other operations to output comes from each table.
i appreciate your help
i found the solution. it is very easy :)
it is just like:
$response['items'][] = array(
'id' => (int)$item['rowid'],
'feed_id' => (int)$item['feed_id'],
'title' => $item['title'],
'feeds' => array(
)
'images' => array(
)
);

Build new custom Array from Wordpress $wpdb->get_results array

I'm currently taking the results of a table and using wp_send_json to using it as a JSON response. The data is encoded as expected, however I'd like to tweak the output a bit by changing the keys, formating, and order. I'm not sure how to rebuild the array and encode as json after so I'm looking for a little bit of help.
$stuff= $wpdb->get_results( $wpdb->prepare("SELECT * FROM wp_table"), ARRAY_A);
wp_send_json($stuff);
As of now the results I get via print_r look as follows.
Array(
[0] => Array(
[id] => 1[gender] => Male[email] => test#loas . com[lat] => 38[long] => - 97[country_srt] => USA[country_long] => UnitedStates
) [1] => Array(
[id] => 2[gender] => Female[email] => femal#test . com[lat] => 38[long] => - 97[country_srt] => USA[country_long] => UnitedStates
)
)
When encoded I get:
[{
"id": "1",
"gender": "Male",
"email": "test#loas.com",
"lat": "45",
"long": "-76",
"country_srt": "USA",
"country_long": "United States"
}, {
"id": "2",
"gender": "Female",
"email": "femal#test.com",
"lat": "98",
"long": "-34",
"country_srt": "USA",
"country_long": "United States"
}]
Thing is, I don't really need some of these values and also need to format some things to output for easy map plotting. For instance the country longform and gender go into an html formatted string. What I'm looking to do is transform this array to result in:
[ idhere: {
"value": "1",
"latitude": "45",
"longitude": "-76",
"tooltip": {"content":"HTML Showing gender variable and country variable"}
}, idhere: {
"value": "2",
"latitude": "98",
"longitude": "-34",
"tooltip": {"content":"HTML Showing gender variable and country variable"}
}]
I think what you need to do is break down the process down into steps (so you can change the data around) instead of sending your sql data to json directly.
build your own array
iterate over your sql result set while adding your own markup
send the output to json
something like:
$preJSON = array();
// select only columns you need
$sql = "SELECT id, gender, country_srt, lat, long
FROM wp_table"
$count = 0; // this is for $preJSON[] index
foreach( $wpdb->get_results( $sql ) as $key => $row ) {
// each column in your row will now be accessible like this:
// $my_column = $row->column_name;
// now we can do:
$value = $row->id;
$latitude = $row->lat;
$longitude = $row->long;
$gender = $row->gender;
$country = $row->country_srt;
$tooltip = array(
"content" => "HTML and stuff" . $gender . "more HTML and stuff" . $country
);
// now we can build a row of this information in our master array
$preJSON[$count] = array(
"value" => $value,
"latitude" => $latitude,
"longitude" => $longitude,
"tooltip" => $tooltip
);
// increment the index
++$count;
}
// after foreach
// send the whole array to json
$json = json_encode( $preJSON );
I believe this should be the basic gist of what you need

How do I remove nested object from an object in CakePHP?

CakePHP API returns result like this:
{
"status": "OK",
"themes": [
{
"Theme": {
"id": "20",
"user_id": "50",
"name": "dwdwdw",
"language_code_from": "cz",
"language_code_to": "en",
"type": "CUSTOM",
"created": "2014-10-19 15:36:05",
"count_of_cards": 0
}
}
]
}
I would like to ask, how can in remove nested Theme object to get result like this?:
{
"status": "OK",
"themes": [
{
"id": "20",
"user_id": "50",
"name": "dwdwdw",
"language_code_from": "cz",
"language_code_to": "en",
"type": "CUSTOM",
"created": "2014-10-19 15:36:05",
"count_of_cards": 0
}
]
}
Here is my CakePHP code:
$this->Theme->recursive = -1;
// GET USER ID
$themeData['user_id'] = $isSessionValid;
// GET ALL THEMES RELATED TO USER
$foundThemes = $this->Theme->find('all', array(
'conditions' => array(
'Theme.user_id' => $themeData['user_id'])
)
);
$themes = array();
// FOREACH THEMES AND GET COUNT FOR CARDS FOR EACH THEME
foreach($foundThemes as $foundTheme) {
// GET COUNT OF QUESTIONS FOR ACTUAL THEME
$countOfCards = $this->Theme->Card->find('count', array(
'conditions' => array(
'Card.theme_id' => $foundTheme['Theme']['id'])
)
);
// APPEND TO ACTUAL ARRAY
$foundTheme['Theme']['count_of_cards'] = $countOfCards;
array_push($themes,$foundTheme);
}
// SET SUCCESS RESPOSNSE
$this->set(array(
'status' => 'OK',
'themes' => $themes,
'_serialize' => array(
'status',
'themes',
)
));
Many thanks for any advice.
You can manipulate CakePHP's array formats using its built in Hash utility: http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash
What I would do would be to flatten the results:
$results = Hash::flatten($results);
Your data array will end up as a single dimensional array looking like this:
$results = array(
'status' => 'OK'
'themes.0.Theme.id' => 20,
...
'themes.1.Theme.id' => 21,
...
);
You can then use string replace to remove "Theme" from your keys:
$keys = array_keys($results);
$keys = str_replace('Theme.', '', $keys);
Then you can use Hash::expand to get your original array, now formatted how you want:
$results = Hash::expand(array_combine($keys, array_values($results)));
I dont think CakePHP supports this. if you want to do this with an easy way check the Set Utility.
http://book.cakephp.org/2.0/en/core-utility-libraries/set.html

return multiple array through json in codeigniter

I want to return multiple array using json in codeigniter like this :
{
"countData"
[
{"flag":1,"count":3}
{"flag":0,"count":0}
{"flag":1,"count":2}
]
}
I already tried :
$faqdata=array(
'count' => $faqdata['countdata']['resultdata']['count'],
)
$listfaqcount['count_Data'][]=$faqdata;
$listfaqcount['flag'] =1;
$j_r=json_encode($listfaqcount);
echo $j_r;
Like this way for two more array .flag would be zero in else condition which I didn't mention here.
How can I do this? Please help.
Thanks in advance
You can do something like this
$listfaqcount['countData'][0] = array(
'flag' => 'flagValue',
'count' => 'countValue'
);
While you looping you change the index with your key like that
$listfaqcount['countData'][1] = array(
'flag' => 'flagValue',
'count' => 'countValue'
);
and so on and while you encoding you can do like this
echo json_encode($listfaqcount);
You need something like array_push
$array['countdata'] = [];
create our sample array sets
$somearray1 = ['flag'=>9,"count"=>5];
$somearray2 = ['flag'=>6,"count"=>6];
$somearray3 = ['flag'=>5,"count"=>7];
$somearray4 = ['flag'=>4,"count"=>8];
Basically what happens here is everytime you loop you push the array inside $array['countdata']
array_push($array['countdata'], $somearray1); //loop 1 format and push
array_push($array['countdata'], $somearray2); //loop 2 format and push
array_push($array['countdata'], $somearray3); //loop 3 format and push
array_push($array['countdata'], $somearray4); //loop 4 format and push
Print the result beautifully or prettily
print_r(json_encode($array,JSON_PRETTY_PRINT));
result would be
{
"countdata": [
{
"flag": 9,
"count": 5
},
{
"flag": 6,
"count": 6
},
{
"flag": 5,
"count": 7
},
{
"flag": 4,
"count": 8
}
]
}
this is just an example you could push your own formatted array.

Confused about MongoDB Query (PHP $and)

I have the following code in PHP to connect to my MongoDB instance:
$connection_string = "mongodb://XXXXXXX:XXXXXX#XXXXX:XXX/myDB";
$mongo_or = new Mongo($connection_string);
$db_or = $mongo_or->selectDB("myDB");
# Pick a collection
$collection_or = $db_or->myCollection;
$findArray = array('$and' => array('user.uid' => 1, 'friend_id' => 2));
$findArray2 = array('$and' => array('user.uid' => 2, 'friend_id' => 1));
$collection_or->remove($findArray);
$collection_or->remove($findArray2);
This never removes any results - even know the content is still there it never get's removed.
if you want the good structure for a $and query just json_decode this :
{
"$and" : [{
"$or" : [{
"civility" : 2
}, {
"civility" : 3
}]
}]
}

Categories