Upsert - php mongodb- Can't insert a new record - php

I'm running the following code. if the record already exists it overrides the existing fields with the new one at $updated_fields_array. But if the record doesn't exist I don't know how to add a new record with new fields ($new_fields_array). which operator should I use? Can someone help me out?
$current_time = time();
$current_mongo_date = new MongoDate($current_time);
$collection = $this->mongo->selectCollection(MONGO_NOTIFY_DB, 'AccountSettings');
$criteria_array=array("email" => $email, "name" => $name);
$updated_fields_array = array (
'last_sent' => $current_time,
'updated' => $current_mongo_date
);
$new_fields_array = array (
'created' => $current_mongo_date,
'updated' => $current_mongo_date,
'email' => $email,
'name' => $name,
'last_sent' => $current_time,
'deleted' => FALSE
);
try {
$collection->update(
$criteria_array,
array('$set' => $updated_fields_array),
array("upsert" => true)
);
} catch (MongoCursorException $mce) {
log_message('error', 'QUERY UPDATE FAILED :: AccountSettings :: ' . print_r($updated_fields_array, true) . ' :: ' . $mce->getMessage());
}
return;

Evgeny's Answer is ok but you are missing one problem
You have duplicate keys in the updated_fields_array and new_fields_array which throws MongoDB WriteException because Mongo will first create the new object and only then update it.
so change
$updated_fields_array = array (
'last_sent' => $current_time,
'updated' => $current_mongo_date
);
$new_fields_array = array (
'created' => $current_mongo_date,
'updated' => $current_mongo_date,
'email' => $email,
'name' => $name,
'last_sent' => $current_time,
'deleted' => FALSE
);
to
$updated_fields_array = array (
'last_sent' => $current_time,
'updated' => $current_mongo_date
);
$new_fields_array = array (
'created' => $current_mongo_date,
'email' => $email,
'name' => $name,
'deleted' => FALSE
);
and change the query (as Evgeny wrote or the Documentation)
$collection->update(
$criteria_array,
array('$set' => $updated_fields_array, '$setOnInsert'=> $new_fields_array),
array("upsert" => true)
);

You can use UPDATE command with upsert option and $set/$setOnInsert operators (see https://docs.mongodb.org/manual/reference/operator/update/setOnInsert/). See example below (note, that you should have unique index on {email:1,name:1})
$current_time = time();
$current_mongo_date = new MongoDate($current_time);
$collection = $this->mongo->selectCollection(MONGO_NOTIFY_DB, 'AccountSettings');
$criteria_array=array("email" => $email, "name" => $name);
$updated_fields_array = array (
'last_sent' => $current_time,
'updated' => $current_mongo_date
);
$new_fields_array = array (
'created' => $current_mongo_date,
'deleted' => FALSE
);
try {
$collection->update(
$criteria_array,
array('$set' => $updated_fields_array, '$setOnInsert'=> $new_fields_array),
array("upsert" => true)
);
} catch (MongoCursorException $mce) {
log_message('error', 'QUERY UPDATE FAILED :: AccountSettings :: ' . print_r($updated_fields_array, true) . ' :: ' . $mce->getMessage());
}
return;

I had to use updateOne
$result = $collection->updateOne(
array('first_id' => 123456,'some_number' => 333333),
array('$set' => array('some_status' => 'Delayed')),
array('upsert' => true)
);

Related

Moodle enrol_manual_enrol_users api error

I have been getting the error below when i try to enroll users to moodle through enrol_manual_enrol_users
Array ( [exception] => invalid_parameter_exception [errorcode] => invalidparameter [message] => Invalid parameter value detected [debuginfo] => enrolments => Invalid parameter value detected: Missing required key in single structure: roleid )
This is my code
$MoodleRest = new MoodleRest('http://localhost/moodle/webservice/rest/server.php', $this->token);
$enrolment = array(
"userid" => $user_id,
"courseid" => $course_id,
"roleid" => 4
);
$enrolments = array(array($enrolment));
$params = array( 'enrolments' => $enrolments );
$result_query = $MoodleRest->request('enrol_manual_enrol_users', $params);
if (!empty($result_query['exception'])) {
print_r(array('Error querying enroll', $result_query));
die();
}
$MoodleRest = new MoodleRest('http://40.81.1.212/moodle/webservice/rest/server.php', $this->token);
$par = array( //e_s_s
'enrolments' => array( //e_m_s
array( //e_s_s
'userid' =>$user_id ,
'courseid' =>$course_id , // PARAM_NUMBER VALUE_REQUIRED[]
'roleid' =>$role_id //PARAM_RAW VALUE_OPTIONAL [] ))
);
print_r($par);
echo "<br><br>";
$result_query = $MoodleRest->request('enrol_manual_enrol_users', $par);
if (!empty($result_query['exception'])) {
print_r(array('Error querying enroll', $result_query));
//die();
}
var_dump($result_query);
echo '</br>************************** Server Response EnrollUser()**************************</br></br>';

mongodb + yii2: How can i push an array/object to mongodb?

I am playing around with yii2 and mongodb and i am stuck at a one point. I have created the CRUD functionality using mongodb GII. Now i am making modification to put the objects of array in my database record.
On creation of a customer i create an object of mileage and push it like this.
$model = new Customer();
if ($model->load(Yii::$app->request->post())) {
$mileage = new mileage(2, 'British Airways', 'Usman', 10000);
$model->mileage = array($mileage);
$model->save();
return $this->redirect(['view', 'id' => (string) $model->_id]);
}
mileage.php
class Mileage {
public $_id;
public $sm_order_id;
public $program;
public $customer;
public $miles;
public function __construct($sm_order_id, $program, $customer, $miles) {
$this->_id = new \MongoId();
$this->sm_order_id = $sm_order_id;
$this->program = $program;
$this->customer = $customer;
$this->miles = $miles;
}
}
and i get the data in the following format in database:
array (
'_id' =>
MongoId::__set_state(array(
'$id' => '569cd9ed9eb8954c2000002c',
)),
'name' => 'Alan',
'email' => 'alan#abc.com',
'address' => 'New York',
'mileage' =>
array (
0 =>
array (
'_id' =>
MongoId::__set_state(array(
'$id' => '569cd9ed9eb8954c2000002b',
)),
'sm_order_id' => 2,
'program' => 'British Airways',
'customer' => 'Wake',
'miles' => 10000,
),
),
)
Now i want a mechanism so i can add more array/objects in mileage node. I have searched a lot but didn't find anything. Same format of the database is mentioned below:
array (
'_id' =>
MongoId::__set_state(array(
'$id' => '569cd9ed9eb8954c2000002c',
)),
'name' => 'Alan',
'email' => 'alan#abc.com',
'address' => 'New York',
'mileage' =>
array (
0 =>
array (
'_id' =>
MongoId::__set_state(array(
'$id' => '569cd9ed9eb8954c2000002b',
)),
'sm_order_id' => 2,
'program' => 'British Airways',
'customer' => 'Wake',
'miles' => 5000,
),
1 =>
array (
'_id' =>
MongoId::__set_state(array(
'$id' => '569cd9ed9eb8954c2000002c',
)),
'sm_order_id' => 7,
'program' => 'Qatar Airways',
'customer' => 'Tony',
'miles' => 2500,
),
),
2 =>
array (
.........
.........
),
)
Ok I have found out the solution long time ago and i thought i should share it here. So i am pushing the 1st object in mileage node like that:
$model = Customer::findOne($customerId);
if ($model->load(Yii::$app->request->post())) {
$mileage = new mileage(2, 'British Airways', 'Usman', 10000);
$model->mileage = array($mileage);
$model->save();
return $this->redirect(['view', 'id' => (string) $model->_id]);
}
So to add another object in mileage node, what we need to do is we need to get the customer object from database and we have to check if there is already an object added in the mileage node and then i have to get that object and push the newly created mileage array/object in it. modified code is below:
$model = Customer::findOne($customerId);
if ($model->load(Yii::$app->request->post())) {
$mileage = new mileage(2, 'British Airways', 'Kamran', 9000);
if (empty($model->mileage) || count($model->mileage) == 0) {
$model->mileage = array($mileage);
} else {
$allUsedMiles = $model->mileage;
array_push($allUsedMiles, $mileage);
$model->mileage = $allUsedMiles;
}
$model->save();
return $this->redirect(['view', 'id' => (string) $model->_id]);
}
I hope this will help someone in the future ;)
Thanks,

error inserting an array in codeigniter

when I insert an array in the db, I get the error "unidentified index" in some of the variables even though they all have their corresponding values. Tried using print_r, and it returned an array with values, but when I try to insert the array, the values become null. I dont understand why and I can't see the error in my code.
here's my controller
public function test()
{
if($this->session->userdata('logged_in'))
{
$session_data = $this->session->userdata('logged_in');
$user_id = $session_data['user_id'];
$table_id = $this->input->post('table');
$start = $this->input->post('start');
$end = $this->input->post('end');
$query = $this->process_resto_list->test($table_id);
if ($query->num_rows() > 0)
{
$row = $query->row();
$resto_id = $row->resto_id;
$table_number= $row->table_number;
$table_size = $row->table_size;
}
//$resto_id = $session_data['user_id'];
$values = array(
'resto_id' => $resto_id,
'diner_id' => $user_id,
'date' => $this->input->post('date'),
'start_time' => $start,
'end_time' => $end,
'table_number' => $table_number,
'number_of_people' => $table_size,
);
if($this->process_resto_list->insert_reservation($values))
redirect('reservation_test/reservation', 'location');
//print_r($values);
}
Here's my model
public function insert_reservation($values)
{
date_default_timezone_set("Asia/Manila");
$data = array(
'resto_id' => $values['resto_id'],
'diner_id' => $values['user_id'],
'date' => date('Y-m-d'),
'start_time' => $values['start'],
'end_time' => $values['end'],
'table_number' => $values['table_number'],
'number_of_people' => $values['table_size'],
);
return $this->db->insert('resto_reservations', $data);
}
When using print_r here's the result of the array
Array ( [resto_id] => 9 [diner_id] => 14 [date] => [start_time] => 11:00 [end_time] => 13:00 [table_number] => 6 [number_of_people] => 4 )
Please help me point out the error. Thank you
In your model. Change values as follows
$data = array(
'resto_id' => $values['resto_id'],
'diner_id' => $values['diner_id'],
'date' => date('Y-m-d'),
'start_time' => $values['start_time'],
'end_time' => $values['end_time'],
'table_number' => $values['table_number'],
'number_of_people' => $values['number_of_people'],
);
I just replaced my model with this. Thanks everyone!
$data = array(
'resto_id' => $values['resto_id'],
'diner_id' => $values['diner_id'],
'date' => date('Y-m-d'),
'start_time' => $values['start_time'],
'end_time' => $values['end_time'],
'table_number' => $values['table_number'],
'number_of_people' => $values['number_of_people'],
);

Unable to insert data into database using codeigniter

I want to insert data into my database. I am using codeigniter framework to build my app.
When I click on submit button,It don't give any error just reload the same page and data in not inserted in database.
Following my code to insert data into database -
public function addSale($saleDetails = array(), $items = array(), $warehouse_id)
{
foreach($items as $data){
$product_id = $data['product_id'];
$product_quantity = $data['quantity'];
$this->updateProductQuantity($product_id, $warehouse_id, $product_quantity);
}
// sale data
$saleData = array(
'reference_no' => $saleDetails['reference_no'],
'warehouse_id' => $warehouse_id,
'biller_id' => $saleDetails['biller_id'],
'biller_name' => $saleDetails['biller_name'],
'customer_id' => $saleDetails['customer_id'],
'customer_name' => $saleDetails['customer_name'],
'date' => $saleDetails['date'],
'note' => $saleDetails['note'],
'internal_note' => $saleDetails['internal_note'],
'inv_total' => $saleDetails['inv_total'],
'total_tax' => $saleDetails['total_tax'],
'total' => $saleDetails['total'],
'total_tax2' => $saleDetails['total_tax2'],
'tax_rate2_id' => $saleDetails['tax_rate2_id'],
'inv_discount' => $saleDetails['inv_discount'],
'discount_id' => $saleDetails['discount_id'],
'user' => $saleDetails['user'],
'shipping' => $saleDetails['shipping']
);
if($this->db->insert('sales', $saleData)) {
$sale_id = $this->db->insert_id();
$addOn = array('sale_id' => $sale_id);
end($addOn);
foreach ( $items as &$var ) {
$var = array_merge($addOn, $var);
}
if($this->db->insert_batch('sale_items', $items)) {
return true;
}
}
return false;
}
Based on https://ellislab.com/codeigniter/user-guide/database/examples.html , it seems to me, that you are missing a line -> $this->db->insert('sales', $saleData); . You do have it inside an if statement, but if statement will not execute it as a code, but check if it returns true.
$saleData = array(
'reference_no' => $saleDetails['reference_no'],
'warehouse_id' => $warehouse_id,
'biller_id' => $saleDetails['biller_id'],
'biller_name' => $saleDetails['biller_name'],
'customer_id' => $saleDetails['customer_id'],
'customer_name' => $saleDetails['customer_name'],
'date' => $saleDetails['date'],
'note' => $saleDetails['note'],
'internal_note' => $saleDetails['internal_note'],
'inv_total' => $saleDetails['inv_total'],
'total_tax' => $saleDetails['total_tax'],
'total' => $saleDetails['total'],
'total_tax2' => $saleDetails['total_tax2'],
'tax_rate2_id' => $saleDetails['tax_rate2_id'],
'inv_discount' => $saleDetails['inv_discount'],
'discount_id' => $saleDetails['discount_id'],
'user' => $saleDetails['user'],
'shipping' => $saleDetails['shipping']
);
$this->db->insert('sales', $saleData);
This should work. You can also check if it succeeds like this ->
return ($this->db->affected_rows() != 1) ? false : true;

$sort and $slice along with $addToSet in php mongodb

$ret = $this->topusers->update (
array("keyword" => $key),
array('$addToSet' => array("users" => array('$each' => array(array('uname' => $uname, 'counter' => $counter))),
'$sort' => array('counter'=>intval(1))
'$slice' => intval(-2)
)),
array("upsert" => true, "w" => 1)
);
var_dump($ret);
What is wrong with this code ? Tried with $push as well. Will get Modified field name may not start with $ error.
Please help
Found a work-around. To get the mongo command directly working. Full native php version is still eluding me..
This will allow you to update a collection with sorted array and limit the array size as well.
Hope its useful for someone else as well.
$command = 'db.topusers.update( { keyword: "'.$key.'" },'.
'{ $push: { users: { $each : [{ name: "'.$uname.'", counter: '.intval($counter).'}],'.
' $sort: { counter: 1 },'.
' $slice: -2'.
'}'.
'}'.
'},'.
'{upsert : true})';
$this->db->execute($command);
Can you try this,
$ret = $this->topusers->update (
array("keyword" => $key),
array("$addToSet" => array("users" => array("$each" => array(array('uname' => $uname, 'counter' => $counter))),
"$sort" => array('counter'=>intval(1)),
"$slice" => intval(-2)
)),
array("upsert" => true, "w" => 1)
);
var_dump($ret);
You are closing the array()s incorrectly.
Try this:
$ret = $test->topusers->update (
array("keyword" => $key),
array(
'$addToSet' => array(
"users" => array(
'$each' => array(array('uname' => $uname, 'counter' => $counter)),
'$sort' => array('counter'=>intval(1)),
'$slice' => intval(-2)
)
),
),
array("upsert" => true, "w" => 1)
);

Categories