I am using the following versions:
PHP -> 5.6.11
MongoDB -> 3.2
MongoDB PHP Driver -> 1.1
When I was looking to install a MongoDB PHP driver here I noticed that the driver named "Mongo" had been deprecated and proceeded to follow the provided link to install the new extension "MongoDB". This will be referred to as php_mongodb. Since I am using a Windows System I had to copy the file php_mongodb.dll to my ../php/ext and added the line extension=php_mongodb.dll to my PHP.ini
Using the now deprecated driver I used to be able to insert a MongoDate() as shown below.
<?php
$connection = new MongoClient();
$database = $connection->selectDB('test');
$coll = new MongoCollection($database, 'users');
$coll->insert(
(object)array(
"createdAt" => new MongoDate()
)
);
?>
The Problem is that with the new php_mongodb this MongoDate() does not seem to be available I receive the error: Fatal error: Class 'MongoDate' not found
What is the equivalent to this using new php_mongodb driver?
Should I consider downgrading my version of MongoDB to 3.0 so that I can use the now legacy Mongo Driver?
Is there a PHP native way to make a date that is of type ISODate?
Should I consider downgrading my version of MongoDB to 3.0 so that I can use the now legacy Mongo Driver?
This is what I've tried to no avail, the following will add a value of type Timestamp to a Document, however it seems that because it is not of type ISODate that I am unable to enforce TTL with this createdAt field:
<?php
require '/vendor/autoload.php';
$date = new MongoDB\BSON\Timestamp(1, date('U'));
$manager = new MongoDB\Driver\Manager("mongodb://127.0.0.1:27017");
$collection = new MongoDB\Collection($manager, "test.users");
$ex = [
"createdAt" => $date
];
$result = $collection->insertOne( $ex );
?>
Another thing I have tried is the below date, however without the MongoDate() functionality I do not know how to insert this as the type ISODate for MongoDB:
date(DATE_ISO8601, date('U'));
not sure if you still need this, but i have been struggling a lot with this. Finally i have been able to figure it out.
$orig_date = new DateTime('2016-01-22 14:00:00');
# or you can use any other way to construct with (int timestamp)
$mongo_date = new MongoDB\BSON\UTCDateTime($orig_date->getTimestamp());
$filter = [
....
....
['timestamp' => ['$gte' => $mongo_date]],
....
....
]
# create command (for example aggregation)
$cmd = new MongoDB\Driver\Command( $filter );
# execute command
$cursor = $manager->executeCommand('my_mongo_db_name', $cmd);
This code works for me.
Related
I am new to MongoDB as I was a SuperFan of MySQL before. I recently moved to this NoSQL thing and loved it but now I am badly trapped at Transactions in MongoDB.
I found some related questions on SO but with no answers or obsolete which does not work with new MongoDB PHP Driver as there are many changes in syntax/functions and I could see many newbie like me are confused between MongoDB Docs and PHP Driver.
I found this way of committing transactions in MongoDB Docs
$client = new MongoDB\Driver\Manager("mongodb://127.0.0.1:27017");
$callback = function (\MongoDB\Driver\Session $session) use ($client)
{
$client->selectCollection('mydb1', 'foo')->insertOne(['abc' => 1], ['session' => $session]);
$client->selectCollection('mydb2', 'bar')->insertOne(['xyz' => 999], ['session' => $session]);
};
// Step 2: Start a client session.
$session = $client->startSession();
// Step 3: Use with_transaction to start a transaction, execute the callback, and commit
$transactionOptions =
[
'readConcern' => new \MongoDB\Driver\ReadConcern(\MongoDB\Driver\ReadConcern::LOCAL),
'writeConcern' => new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY, 1000),
'readPreference' => new \MongoDB\Driver\ReadPreference(\MongoDB\Driver\ReadPreference::RP_PRIMARY),
];
\MongoDB\with_transaction($session, $callback, $transactionOptions);
but this syntax/functions are obsolete for new PHP Driver and it gives following error
Call to undefined function MongoDB\with_transaction()
According to PHP Docs, the new PHP Driver for MongoDB provides these options to commit transaction but I don't understand how? because there is no example given in docs.
https://www.php.net/manual/en/mongodb-driver-manager.startsession.php
https://www.php.net/manual/en/mongodb-driver-session.starttransaction.php
https://www.php.net/manual/en/mongodb-driver-session.committransaction.php
My Question is, How can I update the above code with New PHP Driver's functions? I believe to use
MongoDB\Driver\Manager::startSession
MongoDB\Driver\Session::startTransaction
MongoDB\Driver\Session::commitTransaction
but I don't understand what their syntax is or their arguments etc because of incomplete documentation and no examples. Thanking you in anticipation for your time and support.
Ok, So, I found the answer to my question and I thought it can be helpful for some others
using Core Mongo Extension
$connection = new MongoDB\Driver\Manager("mongodb://127.0.0.1:27017");
$session = $connection->startSession();
$session->startTransaction();
$bulk = new MongoDB\Driver\BulkWrite(['ordered' => true]);
$bulk->insert(['x' => 1]);
$bulk->insert(['x' => 2]);
$bulk->insert(['x' => 3]);
$result = $connection->executeBulkWrite('db.users', $bulk, ['session' => $session]);
$session->commitTransaction();
using PHP Library
$session = $client->startSession();
$session->startTransaction();
try {
// Perform actions.
//insertOne(['abc' => 1], ['session' => $session]); <- Note Session
$session->commitTransaction();
} catch(Exception $e) {
$session->abortTransaction();
}
Note: To make the answer short and to the point, I have omitted some of the optional parameters and used a dummy insert data etc without any try-catch.
If you are running MongoDB instance as standalone version that is for development or testing purpose then you might get error something like
transaction numbers are only allowed on a replica set member or mongos
Then you can enable Replica on a standalone instance following this guide https://docs.mongodb.com/manual/tutorial/convert-standalone-to-replica-set/
I use this MongoDb driver in my application. I like it, because it works well. I can run simple select and insert statements, like:
$em = new MongoDB\Driver\Manager("mongodb://localhost:27017/testdb");
$query = new Query(['name' => 'John']);
$res = $em->executeQuery('users', $query);
But the problem is, I can not find even a single example on making aggregations. PHP documentation does not say a word about this. While, MongoDb documentation seems to use another library:
$collection = (new MongoDB\Client)->test->restaurants;
$cursor = $collection->find([
'name' => new MongoDB\BSON\Regex('^' . preg_quote('(Library)')),
]);
It seems like an example from another library, because MongoDb driver does not have this MongoDB\Client class. There is such a class, but in a deprecated library. So, what is the right way to make aggregations in PHP, using modern MongoDb driver?
This extension provides a minimal API for core driver functionality: commands, queries, writes, connection management, and BSON serialization.
https://www.php.net/manual/en/set.mongodb.php
To execute aggregate command, use MongoDB\Driver\Command
{
aggregate: "<collection>" || 1,
pipeline: [ <stage>, <...> ],
explain: <boolean>,
allowDiskUse: <boolean>,
cursor: <document>,
maxTimeMS: <int>,
bypassDocumentValidation: <boolean>,
readConcern: <document>,
collation: <document>,
hint: <string or document>,
comment: <string>,
writeConcern: <document>
}
https://docs.mongodb.com/manual/reference/command/aggregate/#syntax
I'm trying to return a single document from the database by it's ID.
This is what I have right now.
$id = "5a30ff2c3afc720394000ac2";
$collection = (new \MongoDB\Client(DB_HOST))->DB->posts;
$post = $collection->findOne(['_id' => $id]);
findOne() returns nothing while find() seems to be working. MongoDB documentations mentions that it would not return anything if no document were to be found. However, the document does seem to be in my database.
I have also tried PHP MongoDB documentation example.
$post = $collection->findOne(['_id' => new \MongoId($id)]);
This returns a no class found error.
Mongo by default stores _id as Object
Try this
$collection->findOne(['_id'=> new \MongoDB\BSON\ObjectId("$mongoId")]);
You are using MongoDB driver, but using Mongo driver object.
After much of a struggle I managed to install MongoDB as a service and WAMP. Then on start I got a fatal error saying these would not work:
$m = new Mongo(...);
$m = new MongoClient(...);
In some previous questions on SO people mentioned using a new class called MongoDB/Driver/Manager. I also came across something called MongoDB/Client.
As a beginner to MongoDB I now stand rather confused about how to use/connect to a DB and collection.
I guess I will use:
$m = new MongoDB/Driver/Manager(...);
However,
$db = $m->$dbname; // Seems to cause -> Notice: Undefined Property
$collection = $db->shows; // dito
So all in all what are the difference between MongoDB/Driver/Manager and MongoDB/Client ? And with these new classes how would I correctly connect to a DB or Collection as shown in the previous snippet ? I can't seem to find many examples explaining how to use these new classes, or an up to date correct way of using the new classes for basic functionality.
Thanks,
I think I understand what I am confusing.
Using the MongoDB/Driver/Manager class and others, are part of the basic tools available with the PHP MongoDB Driver. I am guessing it is not recommended using them unless you know what you are doing, or you want something relatively customized.
A more recommendable alternative is to install "mongodb/mongodb-^1.x.x" with a PHP installer such as Composer, which will give you a MongoDB Library. This will give you classes such as the MongoDB/Client class.
Once the library has been installed you can connect like so:
<?php
require 'vendor/autoload.php';
$client = new MongoDB/Client('mongodb://localhost:27017');
// Add URI of MongoDB here
$mydb = $client->mydb; // Add the new DB name or existing DB name here
$collection = $mydb->createCollection('userCollection');
...
?>
<?php
$m = new MongoClient('mongodb://localhost', array(
'username' => 'wa',
'password' => 'password',
'db' => 'wa'
));
I'm using that code snippet to connect and am trying to run commands in PHP to insert / find data in a MongoDB collection or database.
I installed MongoDB and added the mongo.so extension to my php.ini.
What am I doing wrong?
Can you run just the connection code from the command line. Also you should be passing in your connection options in this format:
mongodb://[username:password#]host1[:port1][,host2[:port2:],...]/db
Use this:
<?php
$m = new MongoClient('mongodb://wa:password#localhost/wa');
?>
That will throw any errors you are having on the command line and be easy to diagnose. The responses should be self explainatory. Likely causes:
You are connecting to localhost and do not have a running mongod or mongos on this machine. [ So change tha host and possibly port].
Your user credentials are incorrect
It seems likely that case 1 applies by the very fact you are supplying user credentials, as you would be unlikely to need them if developing on your own machine. It would also be very uncommon to be running MongoDB on the same server as your application in production.
For anyone that stumbles upon this, the MongoClient is depricated and does not work with the current (as of Aug 2018) MongoDB PHP Driver. (which would be installed with the mongodb.dll file, not the *.so file)
A current example of a working connection would be:
<?php
$user = "XXXX";
$pwd = 'XXXX';
$filter = [];
if (isset($_POST['needleID'])) {
$needleID = $_POST['needleID'];
$filter = ['id'=> $needleID];
}
//Manager Class
$connection = new MongoDB\Driver\Manager("mongodb://${user}:${pwd}#localhost:27017");
// Query Class
$query = new MongoDB\Driver\Query($filter);
// Output of the executeQuery will be object of MongoDB\Driver\Cursor class
$rows = $connection->executeQuery('sedwe.defaultConfig', $query);
// Convert rows to Array and sedn result back to client
$rowsArr = $rows->toArray();
echo json_encode($rowsArr);
?>