MongoDB and PHP field with same name can be added? - php

I have a problem and i couldn't figure it out alone so I'm here because i really need some help D
I need to know if i can add a field with the same name, like, id, and id but with a diferente value
$usedWord = array('word' => $word);
// search for the word based on the array
$found = $collection->findOne($usedWord);
// If it returns
if (empty($found)) { // Here, it'll insert
$info = array('word'=> $word,
'id' => $id,
'path' => $path,
'start' => $startOfTheWord,
'end' => $endOfTheWord);
} else {
}
$collection->insert($info);
//disc from servidor
$conn->close();
On the Else part, i tried codes to add a new 'id', path and so on, the question is, can i create another 'id', 'patch' and so on OR i should create 'id1', path1 and so on ?
OBs:. i used $push and couldn't make it work =\

Not sure I got your question, but if you are sking about duplicate fields here what mongo docs says:
BSON documents may have more than one field with the same name. Most
MongoDB interfaces, however, represent MongoDB with a structure (e.g.
a hash table) that does not support duplicate field names. If you need
to manipulate documents that have more than one field with the same
name, see the driver documentation for your driver.
Anyway I think you should avoid duplicate fields in your documents it looks like there's something wrong with document structure design.

Related

Is there another way to provide PDO with the unique column key when using PDO::FETCH_UNIQUE than in the SQL?

I am updating an old internal library to use PHP's PDO extension. In the old code, there's a function where the first parameter was a line of SQL and then the second parameter was an optional column to use as the key. I need to keep this same function signature so I don't break any code.
I'd like to use PDO's FETCH_UNIQUE fetch mode, but it would require me to parse every line of SQL that is passed in and add the key column to the beginning of the select. I'm worried that there are edge cases that I wouldn't think of that would break the call.
Is there another way in PDO to designate which column to use as the key when using PDO::FETCH_UNIQUE other than to add it directly to the column list in the SQL call?
Edit:
Here's some example code and more details:
$db = new Database();
$query = "first_name, last_name, contacts_id from contacts where first_name='George'";
$uniqueKeyField = "contacts_id";
$contact = $db->getRows($query, $uniqueKeyField);
Which would yield:
array (
[34] => array (
"first_name" => "George",
"last_name" => "Smith",
),
[452] => array (
"first_name" => "George",
"last_name" => "Johnson",
)
)
The problem is, I cannot always guarantee that the unique keyField will be first in the list like PDO requires because that was not a requirement of our API before.
After going through the manual, my guess is this is not possible to do with PDO::FETCH_UNIQUE and we will either have to use PDO::FETCH_ASSOC and loop through the results like we used to and build our own array or change every call to the above function in existing code to rearrange the fields so the unique keyfield is first. I was hoping someone knew of a way you could just pass the unique keyfield as an argument somewhere, but my guess is PDO faces the same problem we do - they have to have the keyfield in the query somewhere to pull out and put as the id in the returned array and they don't want to have to try to parse and add it to existing queries, thus the requirement to have it as the first field.

Here is some issue for sorting insensitive sort by in mongodb

On performing the below operation,
$this->mongo_db->order_by(array('first_name' => 'ASC'))->get('users');
the records starting with A-Z come before the records starting with a-z.
I want them to be sorted alphabetically irrespective of their cases.
e.g. AaBbcCDd....Zz
This is because MongoDB, for one, does not have case insensitive indexes ( https://jira.mongodb.org/browse/SERVER-90 ) and for two (the reason why it doesn't) is because it does not have collations yet ( https://jira.mongodb.org/browse/SERVER-1920 ).
Derick Rethans, one of the PHP driver maintainers, recently wrote a blog post with a possible solution to natural language sorting, http://derickrethans.nl/mongodb-collation.html but it still requires a separate field
The problem is because the ascii values of A-Z < a-z.
You need to use the $toLower function in the aggregate pipeline as below,
Project an extra field for each record to hold the first_name in
lowercase.
Sort based on the projected field in ascending order.
Project the required fields.
The Code as acceptable in the mongo shell:
db.collection.aggregate([
{$project:{"users":1,"first_name":{$toLower:"$first_name"}}},
{$sort:{"first_name":1}},
{$project:{"users":1,"_id":0}}
],{allowDiskUse:true})
If your business permits to store the first_name field value in either lowercase or uppercase, you can avoid this problem. And more importantly you can index the first_name field and query, in the case, that the first_field is stored.
As requested, please find below the code in PHP:
$proj1 = array("users" => 1,'first_name' => array ('$toLower' => '$first_name'))
$sort = array("first_name" => 1)
$proj2 = array("users" => 1,"_id" => 0)
$options = array("allowDiskUse" => true)
$collection -> aggregate(array($proj1,$sort,$proj2),$options)

Save php function in mysql

It has been my late-childhood dream to create a game, and now as I actually know how I thought I should fulfill my dream and started working on a little game project in my spare time. It's basically a combat type of game where you have up to 3 units, as well as your opponent, and you take turns ( since it's http, you know that feel ) to attack each other and cast spells and stuff. The issue I came across with is with abilities and how to store them. Basically if I were to store abilities in an array it would look something like
$abilities = array(
0 => array(
'name' => 'Fire ball',
'desc' => 'Hurls a fire ball at your enemy, dealing X damage.'
'effect' => function($data){
$data['caster']->damage($data['target'], $data['caster']->magicPower);
}
),
1 => array(...
);
But if I were to store abilities this way, every time I needed to fetch information about a single ability I would need to load the whole array and it's probably going to get pretty big in time, so that would be a tremendous waste of memory. So I jumped to my other option, to save the abilities in a mysql table, however I'm having issues with the effect part. How can I save a function into a mysql field and be able to run it on demand?
Or if you can suggest another way to save the abilities, I may have missed.
To answer your question related to storing arrays into database like MySQL I would like you to serialize the Array as String. The normal direct serialization not going to work because they don't deal with closure.
You need to use classes like super_closure which can serialize the methods and convert them into string. Read more here
https://github.com/jeremeamia/super_closure
$helloWorld = new SerializableClosure(function($data){
$data['caster']->damage($data['target'], $data['caster']->magicPower);
});
$serializedFunc = serialize($helloWorld);
Now you can create array like this:
$abilities = array(
0 => array(
'name' => 'Fire ball',
'desc' => 'Hurls a fire ball at your enemy, dealing X damage.'
'effect' => $serializedFunc
));
This Array can now be saved directly, serialized or encoded to JSON.
I would recommend you to look at Redis or Memcache for caching query results and don't use MySQL to store functions.
You could have tree tables
spell
id
name
description
spell_effect
id
name
serversidescript
spell_effect_binder
spell_id
spell_effect_id
This would make sure, that your logic is in php files, where ever you would like them to be located, but all the meta of the spells, effects and how they bind together in the database. Meaning you will only load the function/script of the ones in need. Plus, giving you the possibility to append multiple effects to one spell.
//Firedamage.php
public function calculateEffects($level,$caster,$target) {
$extraDamage = 5*$level;
$randDamage = rand(10,50);
$caster->damage( $target, ($randDamage+$extraDamage) );
}
Spell_effect entry
id = 1
name = 'firedamage'
serversidescript = 'Firedamage.php'
spell
id = 1
name = 'Fireball'
description = 'Hurls a fireball at your foe'
spell_effect_binder
spell_id = 1
spell_effect_id = 1

new MongoId objects with php

I am trying to create new objects on MongoDB via PHP with personalized IDs, like this:
$user = Array(
'_id' => "$id",
'name' => $name,
);
The problem with this is that when I query for IDs, I need to use the following:
$query = Array( '_id' => "$id" );
instead of the more appropriate
$query = Array( '_id' => new MongoId("$id") );
forcing me to change all the queries. I thought that I do it by fixing the inserting, by putting '_id' => new MongoId("$id") but, if I use that, it will simply create the default
mongodb id, insead of my personalized one.
How can I fix this?
Thanks in advance
I am a little confused by exactly what you are asking for here, however, I believe I might just understand.
If you are using a _id different to the default ObjectId that MongoDB uses for the primary key of a row then you should not use ObjectId or in fact MongoId to create that object.
You should only use MongoId when you using the default _id that is provided, if you use your own the ObjectId (MongoId) will not function as you expect.
So the answer here is to stop using the MongoId.

Zend Database Last ID of inserted row. (Using postgres)

Ok, got this query (works fine, inserts an all...)
$db = Zend_Db_Table::getDefaultAdapter();
$data = array(
"comment_id" => new Zend_Db_Expr("nextval('comments_comment_id_seq')"),
"comment" => $comment,
"comment_level" => 1,
"is_active" => true,
"status" => 0,
"id" => $id,
"user_id" => $_SESSION['role']['user_id'],
"ts_create" => $created,
"ts_mod" => $created
);
$db->insert($this->_name, $data);
$newID = $db->lastInsertId();
I have even tried even
$newID = $db->insert($this->_name, $data);
And I can't get the ID's value. Its not mysql(i) so I think thats my first issue, as postgres doesn't appear to have an autoincriment in the way I am used to working with it atleast. So I am hoping someone here can help me out. Anyway to get the "comment_id" columns id, on a new inserted item? Cause right now I try lastInsertID and all I get is false or 1 which in either case is wrong.
Well GordonM pointed me in the direction of a specific document for zend, that reading through that, I was able to find what I needed. Unfortunately no one provided an actual answer. So I am going to answer my own question, for those who may stumble across it when they are stuck in a similar position as I just was.. But will give the up-vote to GordonM for getting me in the right direction. Thanks GordonM
Changing:
$newID = $db->insert($this->_name, $data);
To:
$newID = $db->lastSequenceId('comments_comment_id_seq');
From the Zend documentation, databases that use sequences to generate autoincrements (like Postgres) require you to specify the sequence by name in the lastInsertId() call.
Auto incremented fields are implemented as a sequence in PostgreSQL, the database reads from this sequence when inserting a new value. You have to use the name of that sequence when calling lastInsertId() to get the correct value.

Categories