Retrieve fields of Mongo collection in PHP - php

I tried using the fields() method on the cursor:
<?php
$mongo = new Mongo("mongodb://localhost");
print_r($mongo);
$db = $mongo->test;
// access collection
$collection = $db->test;
// execute query
// retrieve all documents
print_r($test);
$cursor = $collection->find();
print_r($cursor);
$fields = $cursor->fields(array("summary" => true));
print_r($fields);
The output is:
Mongo Object ( [connected] => 1 [status] => [server:protected] => [persistent:protected] => )
MongoCursor Object ( )
MongoCursor Object ( )
Looks like the driver and the connection work but I can't retrieve the distinct summarization of the fields.

Assume that we have access to mongodb database with the name db, are going to retrieve data from MyCollection and use MongoDB\Driver\Manager:
$manager = new MongoDB\Driver\Manager( $DB_CONNECTION_STRING );
Then we retrieve data in this case by name with a limit 2 documents and want to get only fields name, age and address among many others. Projection option can be used to specify which fields should be returned using 0 to exclude and 1 to include:
$filter = ['name' => 'John'];
$options = [ 'projection' => ['_id' => 0, 'name' => 1, 'age' => 1, 'address' => 1], 'limit' => 2 ];
$query = new MongoDB\Driver\Query($filter, $options);
$manager->executeQuery('db.MyCollection', $query);
If we need to get all columns, then we simply omit projection option at all as the following:
$filter = ['name' => 'daniel'];
$options = [];
$query = new MongoDB\Driver\Query($filter, $options);
$manager->executeQuery('db.MyCollection', $query);

const HOST = 'localhost';
const PORT = 27017;
const DBNAME = 'test';
const COLLECTION = 'test';
$connectionString = sprintf('mongodb://%s:%d', HOST, PORT);
try {
$connection = new Mongo($connectionString);
$database = $connection->selectDB(DBNAME);
} catch (MongoConnectionException $e) {
throw $e;
}
$collection = $database->selectCollection(COLLECTION);
try{
$query = array();
$specifyKey = array("summary" => true);
$cursor = $collection->find($query , $specifyKey);
}catch(MongoException $e) {
die('Failed to find One data '.$e->getMessage());
}catch (MongoCursorException $e) {
echo "error message: ".$e->getMessage()."\n";
echo "error code: ".$e->getCode()."\n";
}
while ($cursor->hasNext()){
$nextCursor = $cursor->getNext();
//process next cursor
}

After the $cursor variable try an foreach instead. It goes through the cursor results.
foreach($cursor as $document) {
var_dump($document);
}

Related

Mongodb PHP cursor does not fill array

I have a find method in PHP which calls Mongodb, iterates over the cursor and should fill result array which will return. It looks like:
public function find($collection, $where, $select = [], $options = [])
{
$result = [];
if( $select ) foreach ( $select as $col) $options['projection'][$col] = 1; // Need projection in format: ['id' => 1, 'name' => 1, ...]
/** #var Cursor $cursor */
$cursor = $this->mongoDb->{$collection}->find($where, $options);
$cursor->setTypeMap(['root' => 'array', 'document' => 'array', 'array' => 'array']);
//$result = $cursor->toArray(); $result = $cursor;
$i = 0;
foreach ($cursor as $doc) {
if(++$i < 5) Debugger::log($doc);
$doc = $this->parseDocument($doc);
$result[] = $doc;
}
Debugger::log($result);
return $result;
}
The problem is that $result is empty although there are documents in result. It seems $result array is returned before cursor can fill it. It does not make any sense. I can not use $cursor->toArray() cause it has timeout error. How to fix it or how to fix timeout error with toArray()? Collection has above 170 mils. documents, so the timeout is quite a problem.

How to get a single value from MongoDB using PHP?

So I have the following code to get a document from a collection in my database:
$manager = new MongoDB\Driver\Manager('mongodb+srv://<username>:<password>#cluster0.hyqa4.mongodb.net/academic?retryWrites=true&w=majority');
$filter = ['username' => $uname];
$options = ['projection' => ['_id' => 0]];
$query = new MongoDB\Driver\Query($filter, $options);
$cursor = $manager->executeQuery("academic.users", $query);
foreach($cursor as $document) {
print_r($document);
}
I'm able to successfully retrieve a document by searching for the username, so if $uname is "Jon", I get the following output:
stdClass Object ( [username] => Jon [email] => Jon#mail.com [passwd] => pass123 )
However, what I want to do is just return a single value from the document, so if I wanted to get the value for email, it would return:
Jon#mail.com
...so then I could store that value as a variable.
How would I do this?
Std class objects can be accessed via -> operator. So you can user $document->email to access individual email. Is this what you are looking for
$manager = new MongoDB\Driver\Manager('mongodb+srv://<username>:<password>#cluster0.hyqa4.mongodb.net/academic?retryWrites=true&w=majority');
$filter = ['username' => $uname];
$options = ['projection' => ['_id' => 0]];
$query = new MongoDB\Driver\Query($filter, $options);
$cursor = $manager->executeQuery("academic.users", $query);
foreach($cursor as $document) {
print_r($document->email);
}

Zabbix Reading the Api

I'm getting Informations from the Zabbix Api with a PHP library. At the moment I get the "lastvalue" from the json Array:
try {
// connect to Zabbix-API
$api = new ZabbixApi($api_url, $username, $password);
$params = array(
'groupids' => '2',
'real_items' =>TRUE,
'monitored_items' =>TRUE,
'search' => array('name' => 'Disk root used p'),
'selectFunctions' => 'extend',
'output' => 'extend',
'sortfield' => 'name',
'limit' => '1'
);
$trends = $api->itemGet($params); // get data from api
$names = array();
foreach($trends as $trend) { // loop through the returned data
$names[] = $trend->lastvalue;
}
//print_r($names);
} catch(Exception $e) {
// Exception in ZabbixApi catched
echo $e->getMessage();
}
But now I want to get the "lastvalue" plus the "name" of the Item in this Array for example like that: "name"+"lastvalue". How can I get both of them into my array $names[]?
Here is my answer from my comments, hope its what you are looking for!
$trends = $api->itemGet($params);
$names = array();
foreach($trends as $trendKey => $trendValue)
{
$names[$trendKey] = $trendValue;
}
#Test the names array
foreach ($names as $nameKey => $nameValue)
{
print("{$nameKey} = {$nameValue}<br />");
}
Return value:
groupids = 2
real_items = TRUE
...
sortfield = name
limit = 1

Zabbix json get Array without json Object

I have following code to read Item names from the ZabbixAPI:
try {
// connect to Zabbix-API
$api = new ZabbixApi($api_url, $username, $password);
$params = array( 'groupids' => '2 ',
'real_items' =>TRUE,
'monitored_items' =>TRUE,
'search' => array('name' => 'Disk root used p'),
'selectFunctions' => 'extend',
'output' => 'name',
'sortfield' => 'name',
'lastvalue' => 'value'
);
$items = $api->itemGet($params); // get data from api
echo serialize($items);
foreach($items as $item) { // loop through the returned data
echo "<td>".$item."</td>";
}
} catch(Exception $e) {
// Exception in ZabbixApi catched
echo $e->getMessage();
}
With that I get this Output for every Item:
stdClass Object ( [itemid] => 81351 [name] => Disk root used p )
But I only need the 'name' of the Item and not the json objects so the output is just an array like that: itemname1, itemname2....
You can do the following:
$names = array();
foreach($items as $item) { // loop through the returned data
$names[] = $item->name;
}
The $names array will be the array of item names.

PDO ruining my JSON with "

I'm storing a JSON array in a mysql TEXT field using PDO. (encoded with json_encode())
Once I get the data, if I do json_decode the result is NULL.
It seems that PDO is replacing every " with ".
I have already use PDO and JSON together multiple times, but this is the first time I got this problem so I don't understand what's happening.
I'm on PHP 5.4.4
Also, the JSON is sent with AJAX for your information
Thanks if you can help.
Example of JSON in the table :
{"type_voie":"BD","indice_repetition":"T","num_voie":"121","nom_voie":"NOM_RUE","infos_voie":"NOM_RUE2","distribution_speciale":"BP789","cp":"34000","ville":"MONTPELLIER","bureau_distributeur":""}
What i really see with var_dump :
{"type_voie":"BD","indice_repetition":"T","num_voie":"121","nom_voie":"NOM_RUE","infos_voie":"NOM_RUE2","distribution_speciale":"BP789","cp":"34000","ville":"MONTPELLIER","bureau_distributeur":""}
This is inserted with a prepared query
Code for retrieve DATA :
$formDataSQL = '
SELECT * FROM '.$this->prefix.'
WHERE formalite_id = '.$this->proc_id.'
';
$formDataReq = self::$db->prepare($formDataSQL);
$formDataReq->execute();
$formData = $formDataReq->fetch(PDO::FETCH_ASSOC);
Then on the JSON field :
$addrData = json_decode(str_replace('"', '"', $champ['value']), true); // WORKING BUT NOT MAINTAINABLE
$addrData = json_decode($champ['value'], true); // NOT WORKING => NULL + JSON ERROR = JSON_ERROR_SYNTAX
Here is a simplified example of my insert code :
foreach($saveData['personne_physique'] as $field => $value){
if(is_array($value)) $value = json_encode($value);
$param = ':'.$field;
$fields .= $field.'='.$param.', ';
$values[$param] = $value;
}
$fields = trim($fields, ', ');
$persPhysSQL = "UPDATE personne_physique SET $fields WHERE personne_id = ".$this->id;
$persPhysReq = self::$db->prepare($persPhysSQL);
$persPhysReq->execute($values);
Here is how I'm connecting :
$host = 'mysql:dbname='.BDD_NAME.';host='.BDD_HOST.';charset=utf8';
$user = BDD_USER;
$pass = BDD_PASS;
$db = new PDO($host, $user, $pass, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8") );
This is really strange :(
Here is my example script based on your data example:
<?php
try {
$Connection = new PDO('mysql:host=localhost;dbname=testing', USER, PASS);
$Connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e){
echo 'Unable to connect to database' . "\n";
}
$id = $argv[1];
try {
$data = $Connection->prepare('SELECT * FROM `stackoverflow_26399231` WHERE ID = :id');
$data->bindParam(':id', $id, PDO::PARAM_INT);
$data->execute();
while($row = $data->fetch(PDO::FETCH_OBJ)){
print_r($row);
print_r(json_decode($row->data));
}
$Connection = null;
}catch(PDOException $e){
echo 'Error executing query: ' . $e->getMessage() . "\n";
}
?>
The database table looks like this:
*************************** 1. row ***************************
id: 1
data: {"type_voie":"BD","indice_repetition":"T","num_voie":"121","nom_voie":"NOM_RUE","infos_voie":"NOM_RUE2","distribution_speciale":"BP789","cp":"34000","ville":"MONTPELLIER","bureau_distributeur":""}
When you run the script in the CLI, you get this back:
stdClass Object (
[id] => 1
[data] => {"type_voie":"BD","indice_repetition":"T","num_voie":"121","nom_voie":"NOM_RUE","infos_voie":"NOM_RUE2","distribution_speciale":"BP789","cp":"34000","ville":"MONTPELLIER","bureau_distributeur":""}
)
stdClass Object (
[type_voie] => BD
[indice_repetition] => T
[num_voie] => 121
[nom_voie] => NOM_RUE
[infos_voie] => NOM_RUE2
[distribution_speciale] => BP789
[cp] => 34000
[ville] => MONTPELLIER
[bureau_distributeur] =>
)
How does my script differ to yours? I'm not able to reproduce the issue.
UPDATE:
My update script following your example:
try {
$Connection = new PDO('mysql:host=localhost;dbname=testing', USER, PASS);
$Connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e){
echo 'Unable to connect to database' . "\n";
}
$id = $argv[1];
$ary = array(
'foo' => 'bar',
'bar' => 'foo',
'a' => 'b',
'c' => 'd',
'e' => 'f'
);
try {
$fields = 'data=:data';
$values = array('data' => json_encode($ary));
$update = $Connection->prepare("UPDATE `stackoverflow_26399231` SET $fields WHERE ID = $id");
$update->execute($values);
$Connection = null;
}catch(PDOException $e){
echo 'Error executing query: ' . $e->getMessage() . "\n";
}
Using the same script to receive as above but changing from PDO::FETCH_OBJ to PDO::FETCH_ASSOC as that's what you're using, I get this output:
Array
(
[id] => 1
[data] => {"foo":"bar","bar":"foo","a":"b","c":"d","e":"f"}
)
stdClass Object
(
[foo] => bar
[bar] => foo
[a] => b
[c] => d
[e] => f
)
So I can still not reproduce the issue you're having. There must be something different between the two scripts.

Categories