MongoDB update query where field name has a DOT (period) in it - php

So before I ask the question I want to say I do know that Mongo doesn't allow period i.e dot (.) in the field name.
The surprising part is that PHP was able to insert data to mongo with period in it as a field name in a multidimensional array. I use PHP version 5.4 Mongo driver 1.4.
So the array structure is somewaht like:
Array(
["field1"] => "value",
["field2"] => "123",
["field3"] => array( ["abc.def"] => array( ["test"] => "value" )
);
What I want to achieve is changing field2 value from string to integer.
Its huge data and application depends on it, i need to update the type from string to integer or from integer to string, I can control what application inserts in future but what has been entered cannot be changed, Please give me some workaround for the same.
In high hopes somebody will crack an idea upon this..!! ;)

The best workaround that I could find was to use db.collection.update(); though i had to go thru a long procedure of excel and making similar queries for each and every row just after which i realized I could have used db.collection.find().forEach();
So to cut down the solution use forEach to iterate and execute db.collection.update() with condition matching the data and field to update. I formatted the query as a string and then used eval();
If you found a shorter way please do lemme know..!!

Related

Mysql performances: serialize vs columns

Let's say that I have array like the one I posted below and that I need to store it in my MySQL database:
Array(
"Weight" => "10",
"Height" => "17",
"Usage" => "35"
);
Preamble:
I will never update these values
I will never perform a query based on these values
Long story short I only need to store and display this array as it is. Actually I need to use these values to generate graphs. Now I see 2 possible options.
Option 1: even if I will never use a WHERE, ORDER BY, HAVING (...) condition on these values, I store each value separately in a dedicated column (weight, height, usage).
Option 2: I create a single column (stats) where I store a serialized version of the array then, in order generate my graphs, I unserialize each row before using it.
The question is: what's the best approach to store this array in terms of effectiveness and performaces?
In my opinion the second approach is the best but let's say that there are many rows and elements involved in the process. I don't understand if it's faster and ligher to unserialize an array made by 20 elements for 100 rows with PHP or to read plain values stored in 20 columns considering that I need to save lot of them very frequently and simultaneously.
I will never update these values
I will never perform a query based on these values
The second you finalise your code having stored them as serialised values, you'll be asked to perform a query to update anything with a weight above ten.
Just store them in their own columns - not only will this future-proof the code, but it is easier to work with and will take up less drive space in the long run.

MySQL Finding a larger string by knowing only a part of it

I have a string like this:
x26y6z8/0|x999y0z1/1|x1y5z40/9999|etc...
Let's say I know this:
x1y5z40
How can I find the whole part of the string I'm looking for? Which is
x1y5z40/9999
It is actually simple, but the way I'm doing it is absolutely not the correct one, as I'm spamming the database with queries and doing it all with php, which obviously results in it being slow.
To make things more difficult, once I found
x1y5z40/9999
I need to replace it with, for example:
x1y5z40/0
I would like to do it entirely with MySQL if possible, maybe with 1 query, somebody got any idea on how could I do?
Use REPLACE().
update TBL
set content = REPLACE(content , 'x1y5z40/9999', 'x1y5z40/0')
Source: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_replace
I think you are leaving out that the components of the string are separated by |. I think you can do this using MySQL string functions. The following should return the second part:
select substring_index(substring_index(col, '|x1y5z40/', 2), '|', 1)
Ah, now to replace the second part with 0. That will be a bit uglier:
select replace(col,
concat('|x1y5z40/',
substring_index(substring_index(col, '|x1y5z40/', 2), '|', 1),
'|'
),
'|x1y5z40/0'
)
You can also express this as an update, if you are trying to change the data in the database.
By the way, storing lists of things in strings is a very bad idea in SQL. Perhaps you don't have choice. But SQL has an excellent data structure for storing lists, with all sorts of built-in functionality. It is called a table. You should have a junction table with one row per entity and value in the string.

How can I retrieve integer values for integer columns in CakePHP?

When I do a find or fetch, the returned array of values contains string representations of all my columns regardless of the column's data type. This means instead of integer columns returning like:
array( 'field1' => 1 )
they end up as
array( 'field1' => '1' )
Is this expected behavior for CakePHP? Did I misconfigure something?
I thought about writing some code in the afterfind method of my models to call intval on the appropriate columns, but is that really the best solution? Does CakePHP have a better way of handling non-string columns?
You can figure out what kind of field a field in the table your model is from the model property Model::_schema. Based on that you could type cast the values for your fields in the Model::afterFind() callback.
You can also manually check the fields you want to be integers but using _schema would allow you to automate it. You could do this as a behavior for example and attach it to every model that needs this functionality.
So simply iterate over the results and check for the fields you want to be integers and type cast them.
I noticed this too, and apparently it's the result of PDO casting everything to string. I submitted a ticket and hopefully there might be an automatic feature to coercion feature in the future.
Although the clients could convert the data, it's not very 'clean' especially when you might be providing the api to 3rd party developers.

pulling serialized data from mysql

So, there's a field in the db in which I store serialized arrays.
$array = array('count1' => 10, 'count2' => 20, 'count3' => 4);
serialized:
a:3:{s:6:"count1";i:10;s:6:"count2";i:20;s:6:"count3";i:4;}
Would it be possible to pull count1+count2+count3 using a mysql query? I guess I'm looking for something like php's explode. Pretty sure this can't be done, but I thought I'd ask.
I need to pull the highest count1+count2+count3 rows and return the total count. Looping through each row and unserializing wouldn't work since there are TONS of rows.
If you need to access parts of your serialized data via SQL, you need to store them in separate columns.
While it might be possible to use techniques such as regular expressions to access those three values in this string, it would be extremely slow when used in a WHERE criterion as indexes would be useless - not to mention that it would be a huge mess, way worse than using goto in a programming language.
So the solution is to create a new columns and then iterate over all rows, unserialize them, and store the sum into the new column. That might take a while but you'll only need to it once.
Depending on your application it might be better to create three columns and store each value separately.

array type of question

I'm trying to figure out a way to make a small "table" style system in php for about 10 data rows. Because it requires constant editing, I want to replace my mysql system for something in php directly.
The data is 10 rows of:
id
first name
last name
I give the php file the id and want to pull out the first name and last name.
I tried using a associative array, but that turned into a coding mess as my syntax was all over the place.
How can I set this one up properly so i can edit the data easily in a single place and get first and last name of a row by its $id?
edit - example:
id fname lname
1 john ter
2 mark laken
3 peter lars
4 vlad morch
Basically, how do I set that info above up in php such that I can add new rows without too much trouble and the code will still work, and such that it is possible to output the fname and lname from a $_GET of an id value...
Hope that makes sense!
I'm not understanding why you wouldn't want to store constantly changing data in the database, but here is how I would hardcode it:
$data = array(
'id01' => array(
'firstName' => 'Eric',
'lastName' => 'Smith',
),
'id02' => array(
'firstName' => 'John',
'lastName' => 'Turner',
),
...
);
If you were returning this data in an ajax call I'd do it along these line
echo json_encode($data[$id]);
Of course you should also test if the value in $id is in your data array.
I'm not totally sure I understand what you're looking for, but if you want to be able to edit something inline and save it on form input blur, you will have to look beyond PHP and into an AJAX solution. You will likely still want to back this with a database as PHP scripts don't have a continuous runtime, so you can't read all the data into memory and change it directly in memory through user interaction. So what you'll do is read all the data from the DB into a form, then using a little ajax, you will be able to save the form data back to the database everytime a value is changed.

Categories