MongoLab: using php to PUT update using CURL

I have been trying to use MongoLabs api to simplify my life, and for the most part it was working until I tried to push updates to the db using php and curl, anyway no dice. My code is similar to this:

$data_string = json_encode('{"user.userEmail": "USER_EMAIL", "user.pass":"USER_PASS"}');
try { 
$ch = curl_init();

//need to create temp file to pass to curl to use PUT
$tempFile = fopen('php://temp/maxmemory:256000', 'w');
if (!$tempFile) {
    die('could not open temp memory data');
}
fwrite($tempFile, $data_string);
fseek($tempFile, 0); 

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
//curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
//curl_setopt($ch, CURLOPT_INFILE, $tempFile); // file pointer

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, DB_API_REQUEST_TIMEOUT);                                                                    
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);                                                     
curl_setopt($ch, CURLOPT_HTTPHEADER, array(                                                                          
    'Content-Type: application/json',                                                                       
    'Content-Length: ' . strlen($data_string),
    )                                                                              
);   

$cache = curl_exec($ch);
curl_close($ch);
} catch (Exception $e) {
    return FALSE;
}

My problem seems to be with MongoLab's api. The code bit works perfect except for the fact that labs tells me that the data I am passing is an 'Invalid object{ "user.firstName" :"Pablo","user.newsletter":"true"}: fields stored in the db can't have . in them.'. I have tried passing a file and using the postfields, but neither worked.

When I test it on firefox's Poster plugin the value work fine. If someone out there has a better understanding of MongoLabs stuff I would love some enlightenment. Thanks in advance!

Answers


You will need to remove the dots from your field names. You might try going to a schema like this:

{ "user": { "userEmail": "USER_EMAIL", "pass": "USER_PASS" } }

Unfortunately, MongoDB doesn't support using dots in field names. This is because its query language uses the dot as an operator to chain nested field names. If MongoDB were to allow dots in field names dotted queries would become ambiguous without some kind of escaping mechanism.

If this document were legal:

{ "bow.ties": "uncool", "bow": { "ties": "cool" } }

This query would be ambiguous:

{ "bow.ties": "cool" }

Not clear if the document would match or not. Did you mean the field "bow.ties" or the field "ties" nested within the value of field "bow"?

Here's a capture of a mongo shell session demonstrating these ideas.

% mongo
MongoDB shell version: 2.1.1
connecting to: test
> db.stuff.save({"bow.ties":"uncool"})
Wed Jul 18 11:17:59 uncaught exception: can't have . in field names [bow.ties]
> db.stuff.save({"bow":{"ties":"cool"}})
> db.stuff.find({"bow.ties":"cool"})
{ "_id" : ObjectId("5006ff3f1348197bacb458f7"), "bow" : { "ties" : "cool" } }

After sometime working with some other functionality of the project I realized my mistake, and ultimately the source of the confusion.

The curl PUT was intended to send modifier operations to MongoDB. I was sending all my data as JSON and was interrupting decoding it to use in PHP then re-encoding part of it to send back. So the orignal data received looks something like this:

{"userEmail":"p@g.com","pass":"****", "$oid":"5555", "$set":{"user.firstName":"Pablo","user.newsletter":"true"}}

The problem was that I was grabbing the value of "$set" object (in php) and reencoding only the value, {"user.firstName":"Pablo","user.newsletter":"true"} without the operator "$set" and was sending it giving the error. In this case the proper string to send would have been {"$set":{"user.firstName":"Pablo","user.newsletter":"true"}}

While this is a simple mistake I hope that the next time someone does something like this and gets an invalid object error that they are luck enough to find this.


Need Your Help

Regex replace for specific condition

c# regex

I have a string like this:

Unreachable code FOR

c# loops if-statement for-loop while-loop

I have this code and I want to improve it. I want to delete the goto