MongoDB not insert in order with PHP Driver - php

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.

Related

php yii2 how to make automaticly id in query yii2 insert?

i have a code like this ,
$request = Yii::$app->request;
$post = $request->post();
$filesettingid = $post['filesettingid'];
$checkboxValue = $post['selection'];
for($i=0;$i<sizeof($checkboxValue);$i++) {
$store = Yii::$app->db->createCommand('SELECT id FROM store WHERE port='.$checkboxValue[$i])->queryAll();
$storeid = $store[$i]['id'];
Yii::$app->db->createCommand()->insert('tes',
[
'id' => $i+1,
'filesetting_id' => $filesettingid,
'store_id' => $storeid
])->execute();
}
what i want is, each i insert the new data, id will generate automaticly like 1,2,3,4.
the problem in above code is, the ID always be 1.
is it possible to make it real?
so what i want is :
First time insert, id = 1, second is id = 2 , and that is happen automatically.
Have you considered setting database engine to auto increment values with each insert?
Take as an example Yii2 default user table. ID filed is auto incremented, and you don't have to worry about setting it problematically. Every time you send a new insert engine increments ID filed by itself.
See default migration under "advanced template"\console\migrations\m130524_201442_int. (your file name might be different depending on the Yii2 version)
$this->createTable('{{%user}}', [
'id' => $this->primaryKey(),
'username' => $this->string()->notNull()->unique(),
'auth_key' => $this->string(32)->notNull(),
'password_hash' => $this->string()->notNull(),
'password_reset_token' => $this->string()->unique(),
'email' => $this->string()->notNull()->unique(),
'status' => $this->smallInteger()->notNull()->defaultValue(0),
.........
], $tableOptions);
When setting 'id' to primary key database automatically knows to auto increment it. If you already have a table the ID field is not primary key you can use the followign migration:
$this->alterColumn('{{%databaseName}}', 'columnName', $this->integer()->notNull().' AUTO_INCREMENT');
You can also set it from management console, or run a SQL query. Depending on database engine you are using this might look a little different but the concept is the same.
MYSQL:
In MySQL workbench right click on table in question, select Alter Table and check NNm and AI next to column you want auto increment. See Screenshot
Or run command:
ALTER TABLE `dbName`.`nameOfTheTable` MODIFY `columnName` INT AUTO_INCREMENT NOT NULL;
I am a bit rusty on my SQL, so if it does not work let me know I will get you right command.
Hope this helps. Good luck.

PostgreSQL Update Issue With Quotation('')

I'm using PostgreSQL & Codeigniter. There is a table called folio in the database. It has few columns containing remarks1, remarks2, remarks3 as well. Data for the all the other columns are inserted when the INSERT statement executes for the 1st time.
When I try to execute below UPDATE statement later for the below 3 columns, remarks1 column get updated correctly. But remarks2, remarks3 columns are updated with ''.
UPDATE "folio" SET "remarks1" = 'test remark', "remarks2" = '', "remarks3" = '' WHERE "id" = '51';
Given that remarks1, remarks2, remarks3 columns data type is character varying. I'm using Codeigniter active records. At a time all 3 columns could be updated else single column could be updated depending on the user input.
What could be the issue? How can I fix this? Why columns are updated with ''?
As requested the php array in CI would be below
$data = array(
'remark1' => $this->input->post('remark1'),
'remark2' => $this->input->post('remark1'),
'remark3' => $this->input->post('remark1')
);
Function which saves the data contains below two lines only
$this->db->where('id', $folio_id);
$this->db->update('folio', $data);
Those columns are updated with '' because you tell them to?
Let's take a closer look at the query
UPDATE "folio"
SET
"remarks1" = 'test remark',
"remarks2" = '',
"remarks3" = ''
WHERE
"id" = '51';
First you select the table folio for the update.
Then you tell it to update remarks1 through remarks3 with new values. For remarks2 and remarks3 you specify to set them to an empty string. And that's what's going to happen.
Last but not least, you tell it to only apply this update to rows where id equals 51.
So, in order to only update remarks1 you can simply remove the other columns from your update:
UPDATE "folio"
SET
"remarks1" = 'test remark'
WHERE
"id" = '51';
Update:
I'm by far not a CI expert, but from what I see, I'd change the $data array to only contain information for remark1:
$data = array(
'remark1' => $this->input->post('remark1')
);
And (from my understanding) it should only update this single column.

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

How to update record array using cakephp and mongodb

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.

does sfWidgetFormSelect provide a string or an int of the selected item?

I'm having an annoying problem. I'm trying to find out what fields of a form were changed, and then insert that into a table. I managed to var_dump in doUpdateObjectas shown in the following
public function doUpdateObject($values)
{
parent::doUpdateObject($values);
var_dump($this->getObject()->getModified(false));
var_dump($this->getObject()->getModified(true));
}
And it seems like $this->getObject()->getModified seems to work in giving me both before and after values by setting it to either true or false.
The problem that I'm facing right now is that, some how, sfWidgetFormSelect seems to be saving one of my fields as a string. before saving, that exact same field was an int. (I got this idea by var_dump both before and after).
Here is what the results on both var dumps showed:
array(1) {["annoying_field"]=> int(3)} array(1) {["annoying_field"]=>string(1)"3"}
This seems to cause doctrine to think that this is a modification and thus gives a false positive.
In my base form, I have
under $this->getWidgets()
'annoying_field' => new sfWidgetFormInputText(),
under $this->setValidators
'annoying_field' => new sfValidatorInteger(array('required' => false)),
and lastly in my configured Form.class.php I have reconfigured the file as such:
$this->widgetSchema['annoying_field'] = new sfWidgetFormSelect(array('choices' => $statuses));
statuses is an array containing values like {""a", "b", "c", "d"}
and I just want the index of the status to be stored in the database.
And also how can I insert the changes into another database table? let's say my Log table?
Any ideas and advice as to why this is happen is appreciated, I've been trying to figure it out and browsing google for various keywords with no avail.
Thanks!
Edit:
ok so I created another field, integer in my schema just for testing.
I created an entry, saved it, and edited it.
this time the same thing happened!
first if you what the status_id to be saved in the database, you should define your status array like this:
{1 => "a", 2 => "b", 3 => "c", 4 => "d"}
So that way he know that 1 should be rendered like "a" and so on. Then, when saving, only the index should be saved.
About saving in another database, my advise is to modify the doSave method defined by the Form class yo match your needs. I only know how Propel deals with it, maybe this could help:
the doSave method dose something like this:
protected function doSave($con = null)
{
if (null === $con)
{
$con = $this->getConnection();
}
$old = $this->getObject()->getModifiedValues($this);//Define this
$new_object = new Log($old);//Create a new log entry
$new_object->save($con));//save it!
$this->updateObject();
$this->getObject()->save($con);
// embedded forms
$this->saveEmbeddedForms($con);
}
Hope this helps!
Edit:
This is an example extracted from a model in one of my applications and its working ok:
Schema:
[...]
funding_source_id:
type: integer
required: true
[...]
Form:
$this->setWidget('funding_source_id', new sfWidgetFormChoice(array(
'choices' => array(1 => 'asdads', 2 => '123123123' , 3 => 'asd23qsdf'),
)));
$this->setValidator('funding_source_id', new sfValidatorChoice(array(
'choices' => array(1 => 'asdads', 2 => '123123123' , 3 => 'asd23qsdf'),
'required' => true
)));
About the log thing, that could be quite more complex, you should read the current implementation of the doSave method in the base form class, currently sfFomrObject on Symfony1.4., and when and how it delegates object dealing with modified values.
Okay,
It turns out I forgot to do a custom validator to use the array key instead.

Categories