Convert a MongoCursor from ->find() to an array - php

$jokes = $collection->find();
How do I convert $jokes into an array?

You can use PHP's iterator_to_array function, as suggested in example 1 of the MongoCursor docs:
$jokes = $collection->find();
$jokesArray = iterator_to_array($jokes);

iterator_to_array is not working for nesting more than 2 levels,
Using typeMap you can convert root and its document to array, It will work for any level of nesting
findOne($filter,$options)
$options = ["typeMap" => ['root' => 'array', 'document' => 'array']];
$collection->findOne(['myId' => $id ], $options); // returns array
find($filter,$options)
$options = ["typeMap" => ['root' => 'array', 'document' => 'array']];
$collection->find(['myId' => $id ], $options)->toArray();

As a side note to Chris's answer:
array iterator_to_array ( Traversable $iterator [, bool $use_keys =
true ] )
Pay attention to the optional second parameter, if it's set to true (default), the final array will be indexed using the "_id" field from each document.
If you applied a sort in the mongo query, the final array might not be what you expected, meaning that the sort order will not be preserved (unless you set the $use_keys parameter to false)

iterator_to_array() forces the driver to load all of the results into memory, so do not do this for result sets that are larger than memory!
use this
$jokes = $collection->find();
foreach ($jokes as $joke) {
var_dump($joke);
}

a lot easier:
findeOne()->getArrayCopy();
as mentioned before: beware from loading large resultsets and convert them to an array
you can also set your preferences with the typeMap option
'typeMap' =>[
'document' => 'array',
'root' => 'array'
]

find() basically returns MongoDB cursor http://www.php.net/manual/en/mongocollection.find.php
this should work for your case
$cursor = $collection->find();
foreach($cursor as $jokes) {
print_r($jokes);
}

in case if someone came to here, you can also use toArray method.
(mongodb >=1.0.0)
MongoDB\Driver\Cursor::toArray — Returns an array containing all
results for this cursor
$jokes = $collection->find()->toArray();
or :
$jokes = $collection->find();
$jokesArray = $jokes->toArray();

Related

Proper way to get a PHP array() from aggregate() or convert a MongoDB\Driver\Cursor to array()

Some documents on the DB have the field 'Assunto', I wanted to count how many times different values for 'Assunto' occur (ignoring when the field does not exist, so I did this query:
$result = $collection->aggregate([
[ '$match' => ['Assunto' => ['$nin' => [null]]] ],
[ '$sortByCount'=> '$Assunto' ],
[ '$sort' => ['Count' => -1] ]
]);
The query works properly, my issue is with the return from aggregate. From the documentation it returns either "A MongoDB\Driver\Cursor or ArrayIterator object".
Also from the documentation typeMap: "Optional. The type map to apply to cursors, which determines how BSON documents are converted to PHP values. Defaults to the collection’s type map".
I read solutions on Stack Overflow on altering the collection's typeMap to convert the cursor to an array but I couldn't get them to work for my case, from my understanding I have multiple MongoDB\Driver\Cursor and it was returning only the first one of them.
The next solution from Stack Overflow was to encode the cursor to JSON then decode it to an array. Like this:
//Convert $result, a MongoDB\Driver\Cursor to array()
$objects = json_decode(json_encode($result->toArray(),true));
The problem is that this produces an stdClass Object just like this: (sorry for blurry image, happens after resizing)
So, to convert this stdClass to an array I need to do the same code yet again: (sorry for blurry image, happens after resizing)
//Convert stdClass to Array
$array=json_decode(json_encode($objects),true);
This produces the expected output. But doing all this process seems like a waste. What would be the proper way to convert the returned values from aggregate into and array in my case? The entire code snippet in case it helps:
$result = $collection->aggregate([
[ '$match' => ['Assunto' => ['$nin' => [null]]] ],
[ '$sortByCount'=> '$Assunto' ],
[ '$sort' => ['Count' => -1] ]
]);
//Convert $result, multiple MongoDB\Driver\Cursor objects into stdClass Objects
$objects = json_decode(json_encode($result->toArray(),true));
//Convert stdClass Objects into Array()
$array=json_decode(json_encode($objects),true);
return $array;
That was my mistake. I should add true as the second parameter in the json_decode funcion like this:
$array = json_decode(json_encode($result->toArray(),true), true);
This converts the BSON documents to an array instead of an std object in a single line.

Difference between $object->attribute and $object['attribute'] in Laravel

I'm developing with DataTables in Laravel and trying to make an object manually using collect() to create a collection. When I push the collection into the DataTable, there is something wrong, and I can't call my object with this $object->attribute.
After I get the error with that, I already tried to call an attribute with $object['attribute'], and it works well.
Can someone give me insight about the differences and how I can convert $object['attribute'] into $object->attribute?
This is my query to create object
$result = collect();
$item = collect([
'row' => ($key+1),
'item_id' => $value->uid,
'item' => $value->nama_item,
'sub_kategori' => $value->sub_jenis_item->sub_jenis_item,
'kategori' => $value->jenis_item->jenis_item,
'gudang_id' => $id_gudang
]);
$result->push($item);
Accessing $object['attribute'] means $object is an array and accessing $object->attribute means $object is an object.
To convert array to object:
$object = (object) $object;
Additionally, to convert object to array:
$object = (array) $object;
DataTables calls internally toArray() on the collection items when you build the table. This happens during transformation of the data. It will also flatten nested objects (e.g. loaded Eloquent relations in case of an EloquentDataTable) into an array with depth 1 (per row of the table).
You can try the following way,
$result = collect();
$item = collect([
'row' => ($key+1),
'item_id' => $value->uid,
'item' => $value->nama_item,
'sub_kategori' => $value->sub_jenis_item->sub_jenis_item,
'kategori' => $value->jenis_item->jenis_item,
'gudang_id' => $id_gudang
]
);
$result->push($item);
$resultObj = json_decode($result);
foreach($resultObj as $obj){
echo $obj->row;
}

PHP - Convert foreach to arrays

Anyone can help me
I have a little problem with the following code
foreach ($products as $product) {
$product->name;
$product->code;
...
}
My output code with var_dump($products)
array
0 =>
object(stdClass)
...
...
...
1 =>
object(stdClass)
...
...
...
And I need output something like this
$output = array(
array('name' => 'item1', 'code' => 'code1', 'price' => '10.00'),
array('name' => 'item2', 'code' => 'code2', 'price' => '20.00')
);
For this purpose, there is a function is php json_decode()
mixed json_decode ( string $json [, bool $assoc = false [, int $depth
= 512 [, int $options = 0 ]]] )
Need to use this function sensibly.
As you see in the function description,
The function's three parameters:
1) Variable to be converted.
2) Return as associative array.
3) Depth: default => 512. Means upto depth of 512 levels (in case of multi-dimensional array or complex object), the child elements will be converted into arrays if second parameter is set to true.
First encode your variable by json_encode() and the decode it with using
json_decode().
json_decode() 's second parameter should be set to true.
This true means return associative array instead of original type.
Pseudo code:
$output = json_decode(json_encode($yourVar), TRUE);

PHP Prepend two elements to associative array

I have the following array, I'm trying to append the following ("","--") code
Array
(
[0] => Array
(
[Name] => Antarctica
)
)
Current JSON output
[{"Name":"Antarctica"}]
Desired output
{"":"--","Name":"Antarctica"}]
I have tried using the following:
$queue = array("Name", "Antarctica");
array_unshift($queue, "", "==");
But its not returning correct value.
Thank you
You can prepend by adding the original array to an array containing the values you wish to prepend
$queue = array("Name" => "Antarctica");
$prepend = array("" => "--");
$queue = $prepend + $queue;
You should be aware though that for values with the same key, the prepended value will overwrite the original value.
The translation of PHP Array to JSON generates a dictionary unless the array has only numeric keys, contiguous, starting from 0.
So in this case you can try with
$queue = array( 0 => array( "Name" => "Antarctica" ) );
$queue[0][""] = "--";
print json_encode($queue);
If you want to reverse the order of the elements (which is not really needed, since dictionaries are associative and unordered - any code relying on their being ordered in some specific way is potentially broken), you can use a sort function on $queue[0], or you can build a different array:
$newqueue = array(array("" => "--"));
$newqueue[0] += $queue[0];
which is equivalent to
$newqueue = array(array_merge(array("" => "--"), $queue[0]));
This last approach can be useful if you need to merge large arrays. The first approach is probably best if you need to only fine tune an array. But I haven't ran any performance tests.
Try this:
$queue = array(array("Name" => "Antarctica")); // Makes it multidimensional
array_unshift($queue, array("" => "--"));
Edit
Oops, just noticed OP wanted a Prepend, not an Append. His syntax was right, but we was missing the array("" => "--") in his unshift.
You can try this :
$queue = array("Name" => "Antarctica");
$result = array_merge(array("" => "=="), $queue);
var_dump(array_merge(array(""=>"--"), $arr));

MongoDB PHP using $in with array

I'm using MongoDB and PHP and trying to do a $in based on a generated array.
When I specify the same array manually, it works, but when I build it, it return any results with the same data.
There's what I have:
$settings = array();
foreach($items as $item) {
$settings[] = $item['id'];
}
//Settings is the same as this
$setting2 = array(1,2,3,4,5,6,7,8);
//This returns no results
$cursor = $collection->find(array('status' => 0, 'sid' => array('$in' => $settings)));
//This does return results
$cursor = $collection->find(array('status' => 0, 'sid' => array('$in' => $setting2)));
I've checked using
$cursor->info()
And the items in the array are the same.
Any ideas what I'm doing wrong?
Thanks!
It's likely that the data types of the numbers are not the same. Try using var_dump() on the built array, and the specified array. You'll probably see one has them as numbers in a string, and the other as simple integers.

Categories