There are currently many conflicting posts regarding mongodb and php due to the driver version. I am using driver 1.2.7, php 5.6 and the latest mongodb on XAMPP
This is my current code:
$filter = [ 'userID' => $myUserId, 'isSold' => true];
$cmdOne = new MongoDB\Driver\Command([
'distinct' => 'collectionNameHere',
'key' => 'productID',
'query' => $filter
]);
$cursorOne = $connection->executeCommand('DatabaseNameHere', $cmdOne);
$products = current($cursorOne->toArray())->values;
Is there a way to find non-distinct results?
This does not work due to the different mongoDb driver:
MongoDB search in collection
You've to use executeQuery with query filter and projection
$filter = [ 'userID' => $myUserId, 'isSold' => true];
$projection = ['projection' => ['productID' => 1]];
$query = new MongoDB\Driver\Query($filter, $projection);
$cursor = $connection->executeQuery('DatabaseNameHere.CollectionNameHere', $query);
Related
When i use aggregatein PHP, i get error:
MongoResultException: localhost:27017: The 'cursor' option is
required, except for aggregate with the explain argument
I use mongoDB 3.6 and PHP 5.6
Please see the photo
My Code:
$dbconn = new MongoClient();
$c = $dbconn->selectDB("test")->selectCollection("users");
$ops = array(
array(
'$lookup' => array(
'from' => 'news',
'localField' => '_id',
'foreignField' => 'user_id',
'as' => 'user_docs'
)
)
);
$results = $c->aggregate($ops);
var_dump($results);
For other people who may run into the same problem, here is the solution.
The aggregator command was modified in version 3.6, as indicated in the documentation:
Changed in version 3.4: MongoDB 3.6 removes the use of aggregate command without the cursor option unless the command includes the explain option. Unless you include the explain option, you must specify the cursor option.
In Mongo, you could just add the cursor option without specifying any parameter, as specified in the documentation:
cursor: {}
In PHP, you would need to specify the option like this, new stdClass()corresponding to an empty object '{}' in Mongo :
$results = $c->aggregate($ops, ['cursor' => new \stdClass()]);
Here's how to do it for your example :
$dbconn = new MongoClient();
$c = $dbconn->selectDB("test")->selectCollection("users");
$ops = array(
array(
'$lookup' => array(
'from' => 'news',
'localField' => '_id',
'foreignField' => 'user_id',
'as' => 'user_docs'
)
)
);
$results = $c->aggregate($ops, ['cursor' => new \stdClass()]);
var_dump($results);
If you want to take advantage of calling 'cursor' to add parameters, such as batchSize, you can do it like this :
$results = $c->aggregate($ops, ['cursor' => ['batchSize' => 200]]);
All the parameters are listed in the documentation page linked above.
I want use combine MongoDB\Driver\Query and MongoDB\Driver\Command. But it does not work. Who can help me. Thanks!
$filter = ['column1' => ['$ne' =>'abc']];
$options = [
'limit' => 1000,
/* Only return the following fields in the matching documents */
'projection' => [
'column2' => 1,
'column3' => 1,
'column4' => 1,
],
/* Return the documents in descending order of views */
'sort' => [
'created_date' => -1
],
];
$query = new MongoDB\Driver\Query($filter, $options);
$cmd = new MongoDB\Driver\Command([
// build the 'distinct' command
'distinct' => 'collection', // specify the collection name
'key' => 'column5', // specify the field for which we want to get the distinct values
'query' => $query // criteria to filter documents,
]);
$cursor = $mgClient->executeCommand('mydb', $cmd); // retrieve the results
$arr = current($cursor->toArray())->values; // get the distinct values as
I have some php script running on hhvm
I'm trying to get max value of numeric field from my collection in MongoDB 3.2
Here is my aggregation pipeline
$mongo = new \MongoDB\Driver\Manager(MONGODB_HOST);
$myCollection = new \MongoDB\Collection($mongo, "mydb.mycollection");
$pipeline = [
[
'$group' => [
'_id' => 'group_field',
'slId' => ['$max' => '$saleId']
],
]
];
$doc = $myCollection->aggregate($pipeline);
This pipeline perfectly works in mongo shell, but from php $doc contains all documents from my collection and no $group is applied to them
Maybe someone can help me with that?
The aggregation operation is returning all documents from your collection since you are specifying a constant value for the group by key, the string group_field. You need to prefix the group field with the $ character in your _id key value. So for example if your group by key is the name field, you can rewrite the aggregation pipeline as
$mongo = new \MongoDB\Driver\Manager(MONGODB_HOST);
$myCollection = new \MongoDB\Collection($mongo, "mydb.mycollection");
$group_field = '$name';
$pipeline = [
[
'$group' => [
'_id' => $group_field,
'slId' => ['$max' => '$saleId']
],
]
];
$doc = $myCollection->aggregate($pipeline);
Thanks to chridam's answer up here.
I don't know, but maybe this is some kind of magic
So, chridam's answer helped me with $group, so finally my results were grouped by $group_field. But slId still wasn't there. So, here is what i did and it helped:
$f = '$group_field';
$sl = ['$max' => '$saleId'];
$pipeline = array(
array(
'$group' => array(
'_id' => $f,
'slId' => $sl
),
)
);
I just updated mongodb to version 3.2 and updated my php driver to the latest. Here is the docs.
They changed almost everything with this new driver and there is not enough documentation I think. I couldn't find how to count, limit and sort the data with php as before.
I found sort method in mongodb website, but there is nothing about it in php docs and source code.
Is there anyone who has dealt with this new driver? How can I sort and limit my query results with php?
To use the new mongo php driver, unlike the old version which just requires mongo.so or mongo.dll to be installed, you will need to get the package mongodb/mongodb through composer:
composer.phar require "mongodb/mongodb=^1.0.0#beta"
Then you can use this example for an initial try:
<?php
require 'vendor/autoload.php'; // include Composer goodies
$manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$collection = new MongoDB\Collection($manager, "db_name.collection_name");
$result = $collection->find( [ 'id' => '1', 'name' => 'John' ] );
foreach ($result as $entry)
{
echo $entry->id, ': ', $entry->name, "\n";
}
?>
More examples can be found in https://github.com/mongodb/mongo-php-library/blob/master/examples/bulkwrite.php and https://github.com/mongodb/mongo-php-library/blob/master/examples/write.php
The count method can be found in https://github.com/mongodb/mongo-php-library/blob/master/src/Collection.php
sort and limit are the options to add to find() method:
$options = [
'sort' => ['id' => 1],
'limit' => 5
];
$result = $collection->find( [ 'id' => '1', 'name' => 'John' ], $options );
When i am trying this aggregation query on a sample mongo database of 25 entries, It works. But when the same method is applied for entire mongodb of 317000 entries, it doesn't respond. Even it's not showing any kind of error.
What to do for such problems.
$mongo = new Mongo("localhost");
$collection = $mongo->selectCollection("sampledb","analytics");
$cursor = $collection->aggregate(
array(
array(
'$group' => array(
'_id' => array(
'os'=>'$feat_os',
'minprice'=>'$finder_input_1',
'max_price'=>'$finder_input_2',
'feat_quadcode'=>'$feat_quadcore'
),
'count' => array('$sum' => 1)
)
),
array('$out'=>"result")
)
);