How to update record array using cakephp and mongodb - php

I have a problem. I have this structure of db in mongodb:
id:"xxx",
is_validated: "xxx",
validation_code:"xxx",
profile:[
{
profile_pic:"xxx",
firstname:"xxx",
lastname:"xxx",
}
]
I am using cakephp. When I update the record, I use this:
$this->User->set('id', "xxx");
$this->User->set('profile', array('firstname' => 'Benedict'));
$this->User->save()
When I save the record, the whole array of profile is deleted and only saves the "firstname":
id:"xxx",
is_validated: "xxx",
validation_code:"xxx",
profile:[
{
firstname:"xxx"
}
]
I need to be able to save the firstname without deleting the other array records of mongodb using cakephp

Do you not follow the standard convention when using MongoDB? (documentation):
// where '1' is the id of your user
$this->User->read(null, 1);
// set the new value for the field
$this->User->set('profile', array('firstname' => 'Benedict'));
// commit the changes to the database
$this->User->save();
Update
If the above doesn't work, try reading the whole record and modifying accordingly:
// set the active record
$this->User->id = 1;
// read the entire record
$user = $this->User->read();
// modify the field
$user['User']['profile']['firstname'] = 'Benedict';
// save the record
$this->User->save($user);

The reason this is happening is because you are asking for the profile field to be updated with the array that you pass. This then duly replaces the current profile array with yours.
To get round this you will have to pass the complete array in i.e. with the keys you want to keep and their values as well as the keys you want to change.

Related

Laravel/Mysql: unable to set field to null

I am working on a laravel project and trying to duplicate a record in mysql db.
after replication I want to set a field value to null(appointment_status).
everything is working except the new record's value (appointment_status) is the same as the original record even tho I set it to null.
$newAppointment = $appointment->replicate();
//push to get the id for the cloned record
$newAppointment->push();
$newAppointment->duplicated_from_id = $appointment->id;
$newAppointment->appointment_status = null;
$newAppointment->save();
//updating the old appointment
$appointment->duplicated_to_id = $newAppointment->id;
$appointment->save();
Instead of whole code-block, try something like this:
// replicate as the new record with some different fields
$newAppointment = $appointment->replicate()->fill([
'duplicated_from_id' => $appointment->id,
'appointment_status' => null,
])->save();
// update some fields of initial original record
$appointment->update([
'duplicated_to_id' => $newAppointment->id,
]);
For more check out this.

MongoDB not insert in order with PHP Driver

There is a problem in inserting to MongoDB database. It is not insert to database in right order.
We read the writing concern in MongoDB:
http://www.php.net/manual/en/mongo.writeconcerns.php
We use mongoDB 2.6 and PHP driver 1.6 with following sample code:
set_message_sample('1');
set_message_sample('2');
set_message_sample($id) {
$connecting_string = sprintf('mongodb://%s:%d/%s', $hosts, $port,$database), // fill with right connection setting
$connection= new Mongo($connecting_string,array('username'=>$username,'password'=>$password)); // fill with proper authentication setting
$dbname = $connection->selectDB('dbname');
$collection = $dbname->selectCollection('collection');
$post = array(
'title' => $id,
'content' => 'test ' . $id,
);
$posts->insert($insert,array("w" => "1"));
Sometimes the result is inserting "2" before "1" to database. We want to inserting in right order (first "1" and next "2") all the times. I also notice that we order the collection with mongoID which automatically set by mongoDB.
We check many options but the problem not solved. How we could solve it? ( How we could disable something like cache or isolate the insert queue to MongoDB.)
So, i think you could insert the second only after the confirmation of the first one. since the insert is asynchronous, you can't be sure who goes first. So you must insert only after the confirmation of the first one.

Update collection erases all information inside

I am new to MongoDB and trying to perform my first updates.
I have my users collection that is populated by an insert statement. Now, I want to add or insert the field authCode with some data into a specific user.
My problem is that when I perform the following function the whole user data becomes replaced by the information in that update statement. My understanding is that by using upsert I would insert or update a users collection. given that the user already exist I expect just the authCode field to be created or updated.
Could anyone point out what am i doing wrong?
public function addAuthCode( array $userId, $code ) {
$user = $this->db()->user;
$user->update(
$userId,
array( 'authCode' => $code ),
array( 'upsert' => true, 'safe' => true )
);
}
You'll want to take a look at the MongoDB documentation for updates found here: http://docs.mongodb.org/manual/reference/method/db.collection.update/#db.collection.update
Specifically:
Add New Fields
db.bios.update(
{ _id: 3 },
{ $set: {
mbranch: "Navy",
"name.aka": "Amazing Grace"
}
}
)
Notice that in order to add a field, you need to use the $set operator
Chris#MongoLab

update query for Mongodb in yii

How can I update based on _id in mongodb for YII?
What I tried is
$model= new MongoUrls();
$criteria = new EMongoCriteria;
$criteria->userid('==', $userid);
$criteria->screenshot_path('!=', null);
$criteria->screenshot_uploaded('!=', 1);
$availablescreenshots=$model-> findAll($criteria);
if(count($availablescreenshots)>0){
foreach($availablescreenshots as $obj1){
$path_parts = pathinfo($obj1->screenshot_path);
if($social->upload($obj1->screenshot_path, 'test',$path_parts['basename'])) {
$model->updateAll(array('_id'=>$obj1->_id ), array('screenshot_uploaded'=>1) );
}
}
}
But it shows an error "The EMongoDocument cannot be updated because it is new." in Yii .
I want to update a document where _id matches same value
If I am correct in assuming the extension you are using you actually want $model->updateAll() since update() relates to updating the current active record not to running a general query. It is a bit confusing but it is the way Yii works.
As yii mongosuite docs states, updateAll is a bit different in use than usual update. Also, you are using updateAll in loop and as condition you pass single id which not really makes sense. With updateAll you could use criteria to update models. Here you should use partial update like that:
// _id is already set because it comes from db
$obj1->screenshot_uploaded = 1;
// First param to set fields which should be updated
// Set second param to true, to make partial update
$obj1->update(array('screenshot_uploaded'), true);
The method worked for me was
$modifier = new EMongoModifier();
$modifier->addModifier('screenshot_uploaded', 'set', '1');
$criteria = new EMongoCriteria();
$criteria->addCond('_id','==', $obj1->_id );
$model->updateAll($modifier,$criteria );

Inserting array into database Yii

I would like to insert an array into a MYSQL database, preferably using Yii's active record.
For example, I have a an array:
User = array(
fname => "Joe"
lname => "Schmidt"
)
with a User table in my database with columns id, fname and lname. One of the options is creating an object and doing:
$user = new User;
$user->fname = User['fname'];
$user->lname = User['lname'];
$user->save();
However, this seems like so much code for such common functionality. Is there a way to insert an array into the database where array keys match corresponding columns without me writing my own function or doing some SQL query hack? Ideally it uses the already present Active record of Yii.
What you want to do is handled by the framework itself.
You can mass assign like:
$user->attributes=$_POST['User'];
Read more about Mass Assignment
I have never worked with Yii before, so I can't offer a solution using that, but you can serialize the array and store it in the single cell in your database, like so:
$user = array("fname" => "Joe", "lname" => "Schmidt");
$serialized = serialize($user);
//Store the $serialized variable in the database
When you are ready to access it:
//Get your data from the database
$unserialized = unserialize($usersFromDB);
$fname = $unserialized['fname']; //Joe
Hope that helps.
the function is pretty straightforward, try this:
function insert($table, $fields_values = array())
{
$q1 = join(",", array_keys($fields_values));
$q2 = "'".join("','", array_values($fields_values))."'";
$query = "INSERT INTO $table($q1) VALUES($q2)";
// do your DB insert here
}
The main trick is the array to query conversion using join and array_keys / array_values.
Depending the amount of data in array you can write you own function e.g
a) check this backUpdate , modify it to insert /remove render view option
b) Follow this thread
c) Possible traps when inserting multiple records
d) check this associated SOQ
If you know what you are doing its easy to do , you just need to take care of
validations
records exists in associated tables ( if there is FKey involved )
option d). will be a posssible answer if you have simple inserts ( with no associated tables)

Categories