It might be a silly question, but I think it will be useful for all new mongoDB users and not just myself.
I am currently working on a live chat script as a way to learn about mongoDB. I am having trouble with only loading new messages into chat rather than loading all messages and replacing old ones. This is what I have.
My PHP:
try
{
$m = new Mongo(); // connect
$db = $m->selectDB("local");
}
catch ( MongoConnectionException $e )
{
echo '<p>Couldn\'t connect to mongodb, is the "mongo" process running?</p>';
exit();
}
$collection = $db->selectCollection("message");
echo "".$collection." selected";
$cursor = $collection->find();
// iterate cursor to display title of documents
foreach ($cursor as $document) {
echo $document["sender"].": ". $document["message"] . "<br>";
My JS:
function get_new(){
var messages = $.ajax({
type: "POST",
url: "ajax/receive.php",
async: false
}).success(function(){
setTimeout(function(){get_new();}, 10000);
}).responseText;
$('div.messages').html(messages);
}
My messages collection:
"createdAt" => $now,
"sender" => $sender,
"message" => $message
I know that my JS would eventually start using .append(messages), but I really don't know what to do with my PHP. So how do I change my php to only find new messages (older than last set of messages)
Found the answer. Use sessions to store the time of last update. So The PHP code will look like this:
$now = date("Y-m-d H:i:s");
$last = $_SESSION["last_message_ts"];
$session_last = new MongoDate(strtotime($last));
$session_now = new MongoDate(strtotime($now));
$_SESSION["last_message_ts"]=$now;
try
{
$m = new Mongo(); // connect
$db = $m->selectDB("local");
}
catch ( MongoConnectionException $e )
{
echo '<p>Couldn\'t connect to mongodb, is the "mongo" process running?</p>';
exit();
}
$collection = $db->selectCollection("message");
$cursor = $collection->find(array("createdAt" => array('$gt' => $session_last, '$lte' => $session_now)));
// iterate cursor to display title of documents
foreach ($cursor as $document) {
echo $document["sender"].": ". $document["message"];
}
Related
Currently I am using Google Big query to match two tables and export the query result as CSV file in GCS.
I can't find a way to directly export the query result as CSV in GCS through API, whereas it is readily available in Google cloud console.
So I am creating a table dynamically with same column name and type as query output and inserts the record in the table. However as soon as I did it, Streaming buffer is created before actual table is populated with data. It is taking around 90 minutes to mature the table.
If I export that table (with active streaming buffer) as CSV in GCS, sometimes the exported file contains only the column header and no row data is exported.
Is there a way to overcome the situation?
I am using google cloud php API for my code.
Below is the sample working code.
1. We are creating two Table with schema dynamically
$bigQuery = new BigQueryClient();
try{
$res = $bigQuery->dataset(DATASET)->createTable($owner_table, [
'schema' => [
'fields' => $ownerFields
]
]);
}
catch (Exception $e){
//echo 'Message: ' .$e->getMessage();
//die();
$custom_error_message = "Error while creating owner table schema. Trying to create with ".$ownerFields;
sendErrorEmail($e->getMessage(), $custom_error_message);
return false;
}
2. Import two CSV from GCS into created tables.
$bigQuery = new BigQueryClient([
'projectId' => $projectId,
]);
$dataset = $bigQuery->dataset($datasetId);
$table = $dataset->table($tableId);
// load the storage object
$storage = new StorageClient([
'projectId' => $projectId,
]);
$object = $storage->bucket($bucketName)->object($objectName);
// create the import job
$job = $table->loadFromStorage($object, $options);
// poll the job until it is complete
$backoff = new ExponentialBackoff(10);
$backoff->execute(function () use ($job) {
//print('Waiting for job to complete' . PHP_EOL);
$job->reload();
if (!$job->isComplete()) {
//throw new Exception('Job has not yet completed', 500);
// sendErrorEmail("Job has not yet completed", "Error while import from storage.");
}
});
3. Run Big Query to find some matches from both table.
{
//Code omitted for brevity
}
4. Big Query returns the result as array in php. Then We are creating the 3rd table and inserting the query result set into it.
$queryResults = $job->queryResults();
if ($queryResults->isComplete()) {
$i = 0;
$rows = $queryResults->rows();
$dataRows = [];
foreach ($rows as $row) {
//pr($row); die();
// printf('--- Row %s ---' . PHP_EOL, ++$i);
++$i;
$inlineRow = [];
$inlineRow['insertId'] = $i;
foreach ($row as $column => $value) {
// printf('%s: %s' . PHP_EOL, $column, $value);
$arr[$column] = $value;
}
$inlineRow['data']= $arr;
$dataRows[] = $inlineRow;
}
/* Create a new result table to store the query result*/
if(createResultTable($schema,$type))
{
if(count($dataRows) > 0)
{
sleep(120); //force sleep to mature the result table
$ownerTable = $bigQuery->dataset(DATASET)->table($tableId);
$insertResponse = $ownerTable->insertRows($dataRows);
if (!$insertResponse->isSuccessful()) {
//print_r($insertResponse->failedRows());
sendErrorEmail($insertResponse->failedRows(),"Failed to create resulted table for".$type);
return 0;
}
else
{
return 1;
}
}
else
{
return 2;
}
}
else
{
return 0;
}
//printf('Found %s row(s)' . PHP_EOL, $i);
}
5. We are trying to export the 3rd table which contains the result set to GCS.
function export_table($projectId, $datasetId, $tableId, $bucketName, $objectName, $format = 'CSV')
{
$bigQuery = new BigQueryClient([
'projectId' => $projectId,
]);
$dataset = $bigQuery->dataset($datasetId);
$table = $dataset->table($tableId);
// load the storage object
$storage = new StorageClient([
'projectId' => $projectId,
]);
$destinationObject = $storage->bucket($bucketName)->object($objectName);
// create the import job
$options = ['jobConfig' => ['destinationFormat' => $format]];
$job = $table->export($destinationObject, $options);
// poll the job until it is complete
$backoff = new ExponentialBackoff(10);
$backoff->execute(function () use ($job) {
//print('Waiting for job to complete' . PHP_EOL);
$job->reload();
if (!$job->isComplete()) {
//throw new Exception('Job has not yet completed', 500);
return false;
}
});
// check if the job has errors
if (isset($job->info()['status']['errorResult'])) {
$error = $job->info()['status']['errorResult']['message'];
//printf('Error running job: %s' . PHP_EOL, $error);
sendErrorEmail($job->info()['status'], "Error while exporting resulted table. File Name: ".$objectName);
return false;
} else {
return true;
}
}
The Problem is on #5. As the 3rd Table in #4 is in streaming buffer the export job is not working successfully.
Sometimes it is able to export the table correctly and sometimes it is not done. We have tried to give a sleep between #4 and #5 about 120 seconds but the problem remains.
I have seen that the table generated dynamically via API is in streaming buffer for 90 mins. But this is too high.
One of my class files has been spitting out the "There is no active transaction" warning when creating some records. It is the only one doing it and I can't figure out why because all my queries are executing successfully.
My php_errors log has given me zero insight to the issue, nor have any of the other related questions provided any solutions.
try {
App::$DB->beginTransaction();
$rQuery = App::$DB->prepare("INSERT INTO `Cervidae` (`".implode('`, `',array_keys($aSQL)) ."`) VALUES (".implode(",",$aPlaceholders).")");
$rQuery->execute(array_values($aSQL));
$this->_Cervid_ID = App::$DB->lastInsertId();
if (is_array($aData["Treatments"])) {
foreach ($aData["Treatments"] as $sTreatmentName => $sTreatmentData) {
$oTreatmentToCervid = new TreatmentToCervid(array("Treatment_ID" => $sTreatmentData["Treatment_ID"], "Cervid_ID" => $this->_Cervid_ID, "CreatedBy" => $aSQL["CreatedBy"], "UpdatedBy" => $aSQL["UpdatedBy"], "Dose" => $sTreatmentData["TreatmentDose"]), "NEW");
}
}
$oHerdSize = App::getFlat(self::get(array("COUNT(Cervidae.Cervid_ID) AS HerdSize"),array("Cervidae.Herd_ID = $nHerdID","Cervidae.IsActive = 1")));
$rQuery = App::$DB->prepare("UPDATE `Herds` SET `HerdSize` = ".$oHerdSize->HerdSize." WHERE `Herd_ID` = ".$nHerdID);
$rQuery->execute();
App::$DB->commit();
$this->__construct($this->_Cervid_ID, 'ID');
}
catch (Exception $e) {
App::$DB->rollBack();
throw new Exception($e->getMessage());
}
For save data from form to MongoDB database i'm using this code.
if (isset($_POST))
{
$m = new MongoClient();
$db = $m->abst;
$collection = $db->users;
print_r($_POST);
if($collection->find(array('user_id' => $pid)))
{
$collection->update(array('user_id'=>$pid),$_POST);
}
else
{
$document = array_merge(array('user_id'=>$pid),$_POST);
$collection->insert($document);
}
}
How can check user id exist in collection? and if user id exist in collection, data will update. Otherwise new entry saved to collection. where is the mistake?
Try this - maybe it will work for you.
In MongoDB if a record does not exist for given query and if upsert is true then mongodb adds the record as a new record.
$query['user_id'] = $pid;
$object['$set'] = $_POST;
$options = array('w' => true, 'upsert' => true);
$collection->update($query, $object, $options);
try this
if($collection->find(array('user_id' => $pid))->count() == 1)
{
$collection->update(array('user_id'=>$pid),$_POST);
}
I am doing project using mongodb and php. so here I tried to rename existing database using php. so I did following way to rename database.
first I create new database( user new database name)
read all records from old db and insert to new db
then I drop old db
this is my code.
$conn = new \MongoClient('mongodb://example.com:27017', array("connect" => TRUE));
$exist_dbs = $conn->listDBs();
foreach ($exist_dbs["databases"] as $databse) {
if ($databse['name'] == $new_name) {
$new_name_is_exist = true;
}
}
if (!$new_name_is_exist) {
$db = new \MongoDB($conn, $old_name);
//create new database
$db_new = new \MongoDB($conn, $new_name);
$collections = $db->getCollectionNames();
foreach ($collections as $collection) {
//create collection
$new_collection = new \MongoCollection($db_new, $collection);
$mongo_collection = $db->$collection;
$objects = $mongo_collection->find();
while ($document = $objects->getNext()) {
//add records
$new_collection->insert($document);
}
}
$db->drop();
$msg = 'database renamed';
} else {
$msg = 'given database name already exist';
}
$conn->close();
it works fine. but I would like to know is there any better way to rename mongo database using php?
Copy db (php + mongodb):
<?php
$rename = 'oldname';
$name = 'newname';
$mongo = (new MongoClient());
$db = $mongo->admin;
$response = $db->command(array(
'copydb' => 1,
'fromhost' => 'localhost',
'fromdb' => $rename,
'todb' => $name
));
print_r($response);
Drop db (php + mongodb):
<?php
$name = 'oldname';
$mongo = (new MongoClient());
$db = $mongo->$name;
$response = $db->command(array(
'dropDatabase' => 1
));
print_r($response);
$db=new new Mongo();
Copy old_db to new_db
$responseCopy = $db->admin->command(array(
'copydb' => 1,
'fromhost' => 'localhost',
'fromdb' => 'old_db',
'todb' =>'new_db'
));
Now drop old_db
if($responseCopy['ok']==1){
$responseDrop=$db->old_db->command(array('dropDatabase' => 1));
//OR
$responseDrop =$db->old_db->drop();
}
Show Output
print_r($responseCopy);
print_r($responseDrop);
Output will be something like this
Array ( [ok] => 1 )
Array ( [dropped] => old_db [ok] => 1 )
you can use this
$mongo = new MongoClient('_MONGODB_HOST_URL_');
$query = array("renameCollection" => "Database.OldName", "to" => "Database.NewName", "dropTarget" => "true");
$mongo->admin->command($query);
I want to integrate Sitelink with my website using php. For demo they have just provided this code
echo '<p>Testing SiteLink...</p>';
define( 'SITELINK_URL', "https://www.smdservers.net/CCWs_3.5/CallCenterWs.asmx?WSDL");
define( 'SITELINK_CORP_CODE', "CCTST" );
define( 'SITELINK_LOC_CODE', "Demo" );
define( 'SITELINK_CORP_LOGIN', "Administrator" );
define( 'SITELINK_CORP_PASS', "Demo" );
$client = new SoapClient( SITELINK_URL );
$params->sCorpCode = SITELINK_CORP_CODE;
$params->sLocationCode = SITELINK_LOC_CODE;
$params->sCorpUserName = SITELINK_CORP_LOGIN;
$params->sCorpPassword = SITELINK_CORP_PASS;
try
{
$units = $client->SiteInformation( $params );
$result = $units->SiteInformationResult;
}
catch (Exception $e )
{
die( 'Error: '.$e->getMessage().'<br>'.$e );
}
echo htmlentities( $result->any );
But I am not able to understand how to fecth the data and process it using php. I have to Fetch unit sizes and their respective prices. Any help is greatly appreciated. Thanks in advance.
You are not trying to get Units you are getting SiteInformation
add type for $params first:
$params = new stdClass; // as stdClass
$params->sCorpCode = SITELINK_CORP_CODE;
$params->sLocationCode = SITELINK_LOC_CODE;
$params->sCorpUserName = SITELINK_CORP_LOGIN;
$params->sCorpPassword = SITELINK_CORP_PASS;
then:
$units = $client->UnitTypePriceList($params);
$result = $units->UnitTypePriceListResult->any;
and you have to parse the data with DOMDocument, check the tag name you want to display and print it out:
$dom = new DOMDocument;
$dom->loadXML($result);
$xpath = new DOMXPath($dom);
$el = $xpath->query('//Table');
foreach($el as $units){
$UnitID = $xpath->query('UnitID_FirstAvailable', $units)->item(0)->nodeValue;
echo $UnitID;
}
I don't know what are your desired values, but I took UnitID_FirstAvailable as example.
SiteInformation is expecting array not Object and your $params was never declared
define('SITELINK_URL', "http://www.smdservers.net/CCWs_3.5/CallCenterWs.asmx?WSDL");
define('SITELINK_CORP_CODE', "CCTST");
define('SITELINK_LOC_CODE', "Demo");
define('SITELINK_CORP_LOGIN', "Administrator");
define('SITELINK_CORP_PASS', "Demo");
$client = new SoapClient(SITELINK_URL);
$params = array("sCorpCode" => SITELINK_CORP_CODE,"sLocationCode" => SITELINK_LOC_CODE,"sCorpUserName" => SITELINK_CORP_LOGIN,"sCorpPassword" => SITELINK_CORP_PASS);
try {
$units = $client->SiteInformation($params);
header("Content-Type: text/xml");
print($units->SiteInformationResult->any);
} catch ( Exception $e ) {
die('Error: ' . $e->getMessage() . '<br>' . $e);
}
See Live DEMO
I know this is kind of old, but I've been doing some extensive work with the API. First off, you'll want this: SiteLink API Documentation
To get all available units, you could do something like this:
// define API connection credentials
define('SITELINK_URL', "http://www.smdservers.net/CCWs_3.5/CallCenterWs.asmx?WSDL");
define('SITELINK_CORP_CODE', "CCTST");
define('SITELINK_LOC_CODE', "Demo");
define('SITELINK_CORP_LOGIN', "Administrator");
define('SITELINK_CORP_PASS', "Demo");
$client = new SoapClient( SITELINK_URL );
$params->sCorpCode = SITELINK_CORP_CODE;
$params->sLocationCode = SITELINK_LOC_CODE;
$params->sCorpUserName = SITELINK_CORP_LOGIN;
$params->sCorpPassword = SITELINK_CORP_PASS;
$params->lngLastTimePolled = 0;
$params->bTestMode = true;
try
{
$units = $client->UnitsInformationAvailableUnitsOnly_v2($params);
$result = $units->UnitsInformationAvailableUnitsOnly_v2Result;
}
catch (Exception $e)
{
die( 'Error: '.$e->getMessage().'<br />'.$e );
}
echo '<table>';
$formatUnits = new SimpleXMLElement($result->any);
foreach($formatUnits->NewDataSet->Table as $unit){
echo "<tr>\r\n";
echo "<td><a href='#' data-unit-number='".$unit->sUnitName."' data-unit-id='".$unit->UnitID."' data-rate='".$rate."' class='res-unit-link'>".$unit->sUnitName."</a></td>\r\n";
echo "<td>".$unit->sTypeName."</td>\r\n";
echo "</tr>\r\n";
}
echo '</table>';
You could do var_dump($formatUnits) to see all available data in the object that gets returned by SiteLink. The above code is an example from something I made where I used jQuery to grab all of the data- attributes from the link to use for the rental/reservation process.
I hope this helps somebody. I really could have used it when I first started using the API.