Set multiple fields with one update query - php

The following code should work. I could have missed something, but right now I have it as 2 separate update statements and have decided to ask here why this line isn't working.
$this->db->settings->update(array('_id' => $mongoID),
array(
'$set' => array('about' => $about),
'$set' => array('avatar' => $avatar)
)
);
Did I miss something when reading guides or is it only possible to do with separate update statements?

The third argument to MongoCollection::update is an array of options for the update operation.
$this->db->settings->update(
array('_id' => $mongoID),
array('$set' => array('about' => $about, 'avatar' => $avatar))
);

Related

How to update many fields at once in mongoDB PHP? [duplicate]

The following code should work. I could have missed something, but right now I have it as 2 separate update statements and have decided to ask here why this line isn't working.
$this->db->settings->update(array('_id' => $mongoID),
array(
'$set' => array('about' => $about),
'$set' => array('avatar' => $avatar)
)
);
Did I miss something when reading guides or is it only possible to do with separate update statements?
The third argument to MongoCollection::update is an array of options for the update operation.
$this->db->settings->update(
array('_id' => $mongoID),
array('$set' => array('about' => $about, 'avatar' => $avatar))
);

mongoDB, PHP update specific value not all the values

I am having a problem in updating values i get from web service ..
$collection = $modb->$table;
$collection->update(array("id" => (int)$row['id']),
array('$set' => array(
"user_id" => (int)$post_data_array['user_id'],
"story" => (int)$post_data_array['story'],
"surprize_sub1" => (int)$post_data_array['surprize_sub1'],
"surprize_sub2" => (int)$post_data_array['surprize_sub2'],
"surprize_sub3" => (int)$post_data_array['surprize_sub3'],
"exr_solve" => (int)$post_data_array['exr_solve'],
"exr_assessmnt" => (int)$post_data_array['exr_assessmnt'],
"exr_refresh" => (int)$post_data_array['exr_refresh'],
"sound_control" => (int)$post_data_array['sound_control'],
"clock_control" => (int)$post_data_array['clock_control'],
"switch_user" => (int)$post_data_array['switch_user'],
"exr_print" => (int)$post_data_array['exr_print'],
"write_on_wall" => (int)$post_data_array['write_on_wall'],
"switch_letter" => (int)$post_data_array['switch_letter'],
"view_controls" => (int)$post_data_array['view_controls'],
)));
I get these values from end users.. i want the specific field sent to be updated without loosing all the rest of data ..
in this code only sent data is set while removing the rest .. i want to change only sent ones by keeping the rest as they are, please advice
you need to use updateOne instead of update .
updateOne
Use the MongoDB\Collection::updateOne() method to update a single document matching a filter.
$collection = $modb->$table;
$collection->updateOne(array("id" => (int)$row['id']),
array('$set' => array(
// .... array elements
)));

How do I loop through an object and display its data within an associative array

First of all this is my code:
Log::create([
'action' => $event->changes[0], //<- This is my problem
'object_id' => $event->id,
'object_type' => "Account",
'ip_address' => Request::ip(),
'user' => ucfirst(Auth::user()->name),
'time' => Carbon::now()->format('H:i:s'),
'date' => Carbon::now()->format('Y-m-d')
]);
$event->changes is an array which contains many items but i only know how to get 1 specific item at a time using the index [0] or [1] etc.
How do I get all the values to display instead of 1 at a time? Obviously I don't want to create a new log for each single action but I cant figure out how to do this.
As always any help is appreciated thank you.
You need to serialize the $event->changes if you want it within one log entry.
It actually depends on the structure of changes array, but it seems to be an array of strings, so you may for example use the implode(', ', $changes), so the snippet would look the following:
Log::create([
'action' => implode(', ', $event->changes), //<- This is my problem
'object_id' => $event->id,
'object_type' => "Account",
'ip_address' => Request::ip(),
'user' => ucfirst(Auth::user()->name),
'time' => Carbon::now()->format('H:i:s'),
'date' => Carbon::now()->format('Y-m-d')
]);

Optimizing query with large result set

I have a CakePHP model, let's call it Thing which has an associated model called ItemView. ItemView represents one page view of the Thing item. I want to display how many times Thing has been viewed, so I do the following in my view:
<?php echo count($thing['ItemView']); ?>
This works, however as time goes on the result set of this query is going to get huge, as it's currently being returned like so:
array(
'Thing' => array(
'id' => '1',
'thing' => 'something'
),
'ItemView' => array(
(int) 0 => array(
'id' => '1',
'thing_id' => 1,
'created' => '2013-09-21 19:25:39',
'ip_address' => '127.0.0.1'
),
(int) 1 => array(
'id' => '1',
'thing_id' => 1,
'created' => '2013-09-21 19:25:41',
'ip_address' => '127.0.0.1'
),
// etc...
)
)
How can I adapt the model find() to retrieve something like so:
array(
'Thing' => array(
'id' => '1',
'thing' => 'something',
'views' => 2
)
)
without loading the entire ItemView relation into memory?
Thanks!
So it's pretty straight forward, we can make use of countercache - Cake does the counting for you whenever a record is added into/deleted fromItemView:
Nothing to change in your Thing.php model
Add a new INT column views in your things table.
In your ItemView.php model, add counterCache like this:
public $belongsTo = array(
'Thing' => array(
'counterCache' => 'views'
)
);
Then next time when you do addition/deletion via ItemView, Cake will automatically recalculate the counting and cache into views for you, so the next time when you do the query, you also need to make sure you specify recursive = -1 as what #Paco Car has suggested in his answer:
$this->Thing->recursive = -1;
$this->Thing->find(...); //this will returns array of Thing + the field "views"
// --- OR ---
$this->Thing->find(array(
'conditions' => array(
//... your usual conditions here
),
//... fields, order... etc
//this will make sure the recursive applies to this call, once only.
'recursive' => -1
);

How to upsert two fields?

How can I upsert (update if not added) two fields at the same time?
It worked for a single field, but it doesn't work for two anymore.
Am I doing something wrong?:
$db->url->update(
array("url" => $linkurlcache),
array('$set' => array('url' => $linkurlcache, 'pos' => $rand_num)),
array("upsert" => true),
array("multi" => true)
);
I really hate having to answer my own question. I would have deleted it but I couldn't find a solution on any website.
Anyhow, the array("multi" => true) made a lot of sense considering we are calling the update function, but it's wrong.
The correct solution is without it!
Just:
$db->url->update(
array("field1" => $field1),
array('$set' => array('field1' => $field1, 'field2' => $field2)),
array("upsert" => true)
);
Because upsert actually makes an insert (if the query doesn't match).

Categories