mongodb limit the fields to return PHP - php

I have a PHP script that gathers data from MongoDB and prints it. Some options are gathered from $_POST supergoblal. Everything works fine but I can't limit the fields to return using an array.
$results = $db->$table->find($param); //This line works and returns all fields
$results = $db->$table->find($param, array('Descripción','Ocurrencias relacionadas'));//This line works and limit the returned fields to the ones specified.
The following code constructs an array to use as a field limiter parameter:
$fields=implode(',', $_POST[field]);
$fd = array($fields);
print_r($fd) shows:
Array ( [0] => 'Descripción','Ocurrencias relacionadas' )
$results = $db->$table->find($param,$fd);` //This line works and returns all documents but only _id field.
Any ideas? It's driving me mad!
Thanks in advance.

You are running your query in the wrong way. First of all, you don't show what $param is, but let's assume it is a query like:
$param = array( 'field1' => 'foo' );
Then as second argument you pass in an array with two values, but that is not what this method wants. The second argument is an array of fields to return, in the following format:
array( 'Descripción' => 1, 'Ocurrencias relacionadas' => 1 );
You pass in the following:
array( 0 => 'Descripción', 1 => 'Ocurrencias relacionadas');
Which means to only show the fields with the names 0 and 1 (which likely don't exist). The _id field is always return so that's why it shows up.
What you need to do, is to pass in the field names as keys in the second argument to find():
$fields=implode(',', $_POST[field]);
$fd = array($fields);
$fd = array_flip($fd); // << important to make the values keys and they keys values: php.net/array_flip
$results = $db->$table->find($param, $fd);

Related

Array to string conversion error in Code Igniter when inserting array of data into table in database

I'm trying to insert an array of data into a table in database but an error said Array to string conversion error
This is the post function in my controller, first i post an array of data. The values of the array will be the names, and numbers, they are not id. The id is only kodejdwl. This will be pass to my model
function index_post() {
$data = array(
'kodejdwl' => $this->post('kodejdwl'),
'tahun_akad' => $this->post('kode_tahun_akad'),
'semester' => $this->post('semester'),
'mk' => $this->post('mk'),
'ruangan' => $this->post('ruangan'),
'nama_dosen' => $this->post('nama_dosen'),
'namakelas' => $this->post('nama_kelas'),
'jam_mulai' => $this->post('jam_mulai'),
'jam_selesai' => $this->post('jam_selesai'),
);
}
After the data from above code is passed to the model. I created some new variables which are the id of each the name of the value in the array data. e.g if the value of data['mk'] is Website then the id will be 1 and that id will be stored in variable $kodemk and i do it to each value in the data. Then i created new_data which stores array of the id's which i previously made. Then i insert that array into one table in my database. I thought it would be fine but it said Array to string conversion error. What should i do so i could insert that array into the table in my database?
public function insert($data){
$this->db->select('thn_akad_id');
$tahunakad_id = $this->db->get_where('tik.thn_akad',array('tahun_akad'=>$data['tahun_akad'],'semester_semester_nm'=>$data['semester']))->result();
$this->db->flush_cache();
$this->db->select('kodemk');
$kode_mk = $this->db->get_where('tik.matakuliah',array('namamk'=>$data['mk']))->result();
$this->db->flush_cache();
$ruangan = $this->db->get_where('tik.ruangan', array('namaruang' => $data['ruangan']), 1)->result();
$this->db->flush_cache();
$this->db->select('nip');
$nip_dosen = $this->db->get_where('tik.staff',array('nama'=>$data['nama_dosen']))->result();
$this->db->flush_cache();
$this->db->select('kodeklas');
$kodeklas = $this->db->get_where('tik.kelas',array('namaklas'=>$data['namakelas']))->result();
$this->db->flush_cache();
$this->db->select('kode_jam');
$kode_mk = $this->db->get_where('tik.wkt_kuliah',array('jam_mulai'=>$data['jam_mulai'],'jam_selesai'=>$data['jam_selesai']))->result();
$this->db->flush_cache();
$new_data = array(
'kodejdwl' => $data['kodejdwl'],
'thn_akad_thn_akad_id' => $tahunakad_id,
'matakuliah_kodemk' => $kode_mk,
'ruangan_namaruang' => $ruangan,
'staff_nip' => $nip_dosen,
'kelas_kodeklas' => $kodeklas,
);
$insert = $this->db->insert('tik.jadwal_kul', $new_data);
return $this->db->affected_rows();
}
You probably want to use row() instead of result() because it'll contain only one result that you want. If you want to use result() and store multiple values then you'll have to use implode to concatenate them and store it as a string.
I've written a possible solution for your problem; Some things were missing, so I've mentioned them in the comments. See if this helps you.
public function insert($data){
$this->db->select('thn_akad_id');
$tahunakad_id = $this->db->get_where('tik.thn_akad',array('tahun_akad'=>$data['tahun_akad'],'semester_semester_nm'=>$data['semester']))->row(); // use row here
$this->db->flush_cache();
$this->db->select('kodemk');
$kode_mk = $this->db->get_where('tik.matakuliah',array('namamk'=>$data['mk']))->row();
$this->db->flush_cache();
// remove your_ruangan_column with your desired column name
$this->db->select('your_ruangan_column');
$ruangan = $this->db->get_where('tik.ruangan', array('namaruang' => $data['ruangan']), 1)->row();
$this->db->flush_cache();
$this->db->select('nip');
$nip_dosen = $this->db->get_where('tik.staff',array('nama'=>$data['nama_dosen']))->row();
$this->db->flush_cache();
$this->db->select('kodeklas');
$kodeklas = $this->db->get_where('tik.kelas',array('namaklas'=>$data['namakelas']))->row();
$this->db->flush_cache();
// Not sure where this ↓↓ is being used but you can use it the same way as others
$this->db->select('kode_jam');
// duplicate variable name here ↓↓ (fix this)
$kode_mk = $this->db->get_where('tik.wkt_kuliah',array('jam_mulai'=>$data['jam_mulai'],'jam_selesai'=>$data['jam_selesai']))->row();
$this->db->flush_cache();
$new_data = array(
'kodejdwl' => $data['kodejdwl'],
'thn_akad_thn_akad_id' => $tahunakad_id->thn_akad_id, // {$tahunakad_id} consists an object with the key {thn_akad_id}-- table_column_name
'matakuliah_kodemk' => $kode_mk->kodemk, // ...
'ruangan_namaruang' => $ruangan->your_ruangan_column, // ...
'staff_nip' => $nip_dosen->nip, // ...
'kelas_kodeklas' => $kodeklas->kodeklas // ...
);
$insert = $this->db->insert('tik.jadwal_kul', $new_data);
return $this->db->affected_rows();
}
Your are making a total of 7 separate trips to the database. Best practice recommends that you always minimize your trips to the database for best performance. The truth is that your task can be performed in a single trip to the database so long as you set up the correct INSERT query with SELECT subqueries.
I don't know what your non-English words are, so I will use generalized terms in my demo (I've tested this successfully in my own CI project). I am also going to reduce the total subqueries to 3 to reduce the redundance in my snippet.
$value1 = $this->db->select('columnA')->where('cond1', $val1)->get_compiled_select('childTableA');
$value2 = $this->db->select('columnB')->where('cond2', $val2)->get_compiled_select('childTableB');
$value3 = $this->db->select('columnC')->where('cond3', $val3)->get_compiled_select('childTableC');
return (int)$this->$db->query(
"INSERT INTO parentTable
(column1, column2, column1)
VALUES (
($value1),
($value2),
($value3)
)"
);
// to mirror your affected rows return... 1 will be returned on successful insert, or 0 on failure
Granted this isn't using the ActiveRecord technique to form the complete INSERT query, but this is because CI doesn't allow subqueries in the VALUES portion (say, if you were to use the set() method). I am guessing this is because different databases use differing syntax to form these kinds of INSERTs -- I don't know.
The bottom line is, so long as you are fetching a single column value from a single row on each of these sub-SELECTs, this single query will run faster and with far less code bloat than running N number of individual queries. Because all of the variables involved are injected into the sql string using get_compiled_select() the stability/security integrity should be the same.

Convert array to list of params for Eloquent

I'm trying to use the Eloqunt avg function. When I pass in my columns as a list of params, it works;
$this->avg('column_two','column_one');
But when I pass in an $array it doesn't;
$this->avg($array);
Here is a dd (like a var_dump of that array so you know what I'm talking about;
array:6 [▼
0 => "column_0"
1 => "column_1"
2 => "column_2"
3 => "column_3"
4 => "column_4"
5 => "column_5"
]
I get a really bizarre error;
ErrorException in Grammar.php line 58:
strtolower() expects parameter 1 to be string, array given
This might seem like a basic array problem, but how can I convert that array to a list of params?
The best I can do is implode;
$array = implode(',', $array);
But that will just return an SQL error;
ERROR: column "example_0,example_1" does not exist
Try with -
function quote($el){
return '"'.$el.'"';
}
$quotedArr[] = array_map('quote', $array);
$paramStr = implode(',', $quotedArr);
$this->avg($paramStr);
You're looking for the PHP call_user_func_array() function.
You would use it like this:
$result = call_user_func_array([$this, 'avg'], $array);
The first parameter is a callable. The second parameter is the array of parameters to send to the callable.
Having said that, I'm not sure if your code is working the way you expect. Taking a look at the code, it seems like the avg() method only accepts one column in the first place. Are you sure you're getting what you want?

Modx xPDO getMany not returning expected results

I'm not sure what is going on here, but I'm trying to retrieve some budgets from a modx/xpdo object and getting unexpected results. From the code below, both foreach loops return the same results [that of the first getMany call. 2 items] if I switch the order of the getmany calls I get only one result for both foreach loops.
$tipa = $this->modx->getObject('Tipa', array('id' => $id, 'token' => $token));
// should retrieve two objects
$tipa_sub_budgets = $tipa->getMany('TipaBudget', array('budget_type_id:!=' => '999'));
foreach($tipa_sub_budgets as $sb){
echo $sb->get('id');
}
// should retrieve one object
$tipa_primary_budgets = $tipa->getMany('TipaBudget', array('budget_type_id' => '999'));
foreach($tipa_primary_budgets as $tb){
echo $tb->get('id');
}
I'm not sure what is happening here. What is the correct way to grab 2 sets of objects from the $tipa object?
I think whereas xPDO::getObject() can be passed the criteria either as an array or an instance of xPDOCriteria, xPDOObject::getMany() expects only an instance of xPDOCriteria meaning the array will not work.
Try passing an instance of xPDOCriteria like so...
$criteria = $this->modx->newQuery("TipdaBudget"); // classname, not the alias
$criteria->where(array("budget_type_id:!=" => 999));
$tipa_sub_budgets = $tipa->getMany("TipaBudget", $criteria);

Why am I getting a dictionary as a result when the result should be an array?

I am using Doctrine in my PHP app to return a result set using the following code
$dm = $this->get('doctrine.odm.mongodb.document_manager');
$query = $dm->createQueryBuilder('SomeBundle:Listing')
->select('title')
->field('userId')->equals(1);
$listings = $query->getQuery()->execute();
$listings_array = $listings->toArray(); <--- WHY NOT RETURNING AN ARRAY?????
$data = array('success'=>true,'listings' => $listings_array, 'displaymessage' => $classifieds->count(). " Listings Found");
What gets out out is the following:
{"success":true,"listings":{"50831582253b4acf09000000":{"id":"50831582253b4acf09000000","title":"fddfds","assets":[],"discussions":[]}},"displaymessage":"1 Listings Found"}
I am wanting an array and not a dictionary.
Any help?
I havent messed with the ODM much but i suspect Doctrine always uses the key for the record as the key in the array when calling toArray on a collection, it makes it easier for most of the cases when you would want to do this, especially since there is no distinction in php between a dict/hash and an array.
Call array_values on it if you want a numerically indexed array.
$data = array(
'success'=>true,
'listings' => array_values($listings_array),
'displaymessage' => $classifieds->count(). " Listings Found"
);

How to create php array from mysql result, perform calculation, resort array, present results

I have a photo website on which I am trying to perform a query against a MySQL database. The query is against a concatenated field of 'title' and 'keyword' called 'title_keyword'.
I want to take the search results and sort them by a newly formed variable called 'sort_priority' which is checking to see if the search word is in the 'title' field. If it is in the 'title' field then I want to assign a value of 1 and if not in the title field then a value of 2. The resulting array will be sorted by 'sort_priority' and output to the screen.
Here is the logic I am using with PHP and MySQL:
1) Query the MySQL database and assign variables. (This works just fine)
2) Take the results, assign each field to a variable, create a new variable that performs a calculation on one of the variables returned
$data_array=array();
// get each row
while($row = mysql_fetch_array($result))
{
//get data
$image_id = "{$row['image_id']}";
$title = "{$row['title']}";
$imageurl = "{$row['imageurl']}";
// Create sort_priority to identify if search word is in title field.
//If it is then set to 1 to force this higher in the result list after sorting
$sort_priority = 2;
if(stristr($title,$search))
{ $sort_priority = 1;}
Everything above this point works. Now for the part I'm stumped on. How to create and add data to the array and then sort on my new $sort_priority variable.
Here is what I've written but it just doesn't work**
// Create array and sort by title then keyword (tk_sort)
$data_array = array(
'image_id' => $image_id,
'title' => $title,
'imageurl' => $imageurl,
'sort_priority' => $sort_priority);
// Obtain a list of columns
foreach ($data_array as $key => $row) {
$image_id[$key] = $row['image_id'];
$title[$key] = $row['atitle'];
$imageurl[$key] = $row['imageurl'];
$sort_priority[$key] = $row['sort_priority'];
}
// Sort the data with volume descending, edition ascending
// Add $data as the last parameter, to sort by the common key
array_multisort($sort_priority, SORT_ASC);
// end of array creation and sort
3) Output the newly sorted array to a table
Not sure how to get the data out of it. Do I have to use a loop or something?
You could just let MySQL do the majority of the work. This should work (haven't tried it myself):
SELECT CONCAT_WS('-', `title`, `keyword`) AS search_term,
IF( INSTR(`search_term`, 'your_search_value_here') > 0, 1, 2 ) AS priority_key,
`image_id`, `imageurl`
FROM table_name_here
ORDER BY `priority_key`;
HTH.

Categories