What are we doing here?

This blog includes a series of videos and references to help new users or enthusiasts better understand how to use open source and free technology tools. The quick links includes more information for accessing many of the tools covered along with other references to learn more for taking advantage of these tools.

Click HERE to see the full list of topics covered!
Showing posts with label MongoDB. Show all posts
Showing posts with label MongoDB. Show all posts

Backing up MongoDB

Explored in previous posts and videos, MongoDB is a great way to store information without a schema. All of the information is stored in a JSON like format called BSON which essentially are documents, but similar to a SQL Database the data cannot be directly read on the host system. 

I was interested in learning some more about how to backup the files. Turns out that MongoDB provides a dump tool similar to MySQL called mongodump and mongorestore

To get started one can run the following command on their host system or container. If you used the MongoDB Docker image, the mongodump command can be run inside the container directly. 

Local Run

mongodump -u=<user> -p=<password> --authenticationDatabase=admin --db=<database to download>

The part '--authenticationDatabase' is important. On the MongoDB container the users allowed to access the database are specified are in that 'admin' database on the Mongo instance, and it must be defined in the mongodump command for the connection to be successful.

Similar to mysqldump, the mongodump command can also be used from a remote host.

Install the MongoDB Command Line Database Tools on the remote host. They offer the tools for Windows, Linux, and MacOS. 

*Note on Fedora 36, using the RedHat/CentOS 8.0 package worked. *

Modify the previous command to the below:

Remote Run

mongodump --host=<Domain/IP> --port=<Mongo service port - default is 27017> -u=<user> -p=<password> --authenticationDatabase=admin --db=<database to download>

Assuming a connection can be made all of the database files and relevant metadata will come down to the directory where the command was run. A successful run will look similar to the below. 

Once complete you will see a directory called 'dump' with the database(s) listed as directories inside. 

To specify the output location on the local system (the system being used to access and backup the MongoDB instance) you may use the '-o' or '--output' flag. 

Remote Run | Specify Download Location

mongodump --host=<Domain/IP> --port=<Mongo service port> -u=<user> -p=<password> --authenticationDatabase=admin --db=<database to download> -o=<directory location>

Restoring data from a Mongodump

The companion utility to mongodump is mongorestore. Mongorestore works similarly to mongodump, but the user specifies the db and the back up files. 

mongorestore --host <Domian/IP:Port> --authenticationDatabase=admin -u <user> -p <password> -d <db to restore> <backup folder location>

One additional tip: 

If the container was installed using the same docker-compose from the PHP and MongoDB tutorial, the port for the MongoDB Instance isn't exposed on the local system. This is good from a security standpoint. The companion web server accesses using the hostname from the private Podman / Docker network. To access the container host from the physical machine you need to use the IP address of the MongoDB container itself.

Using either Docker or Podman, run the inspect command to check to find the Network information. 

sudo podman inspect <container name or ID> | grep "IPAddress" OR
sudo docker inspect <container name or ID> | grep "IPAddress"

Additional information:

Information about using mongodump

Information about using mongorestore

Adding Comments to Posts - MongoDB and PHP

This article explores adding a comments section to blog or forum posts. 

Using my previous project 'OutNoteOrganizer' - which still needs a better name, but all the good ones I could think of were taken - I thought about the design and felt it needed to have a comment section. 

Similar to say for example Reddit, though not public, teams or groups of people could want to leave comments on the initial post. The other thing I didn't like about the initial design was that anyone in the associate group could edit and change the content without a good way from the UI to track what was changed. 

Now the current version only allows the original post author to edit the post, and other group members with access to the post can leave comments.

How I got here?

In terms of how I visualized the code structure, previously I was hung up thinking that comments should be fields in the post itself. For example comment 1, comment 2, etc. However, while it might be possible to do that, it's complex if you want to have an unlimited number of comments to a post. Adjust the concept a bit and you can think of comments that link to the post but are stored in a different table (in MongoDB a different collection) called 'comments'.


Again with MongoDB, there is no need to 'prime' or 'setup' the table. Just from the code tell the DB what fields you want and it will accept the values as a BSON object. 

Once you have an HTML form filled in you really only need this code to create a new collection called 'comments'. 

$col = $db -> comments; //Point the query at the new collection comments (this will create the collection)

//Collect data from an HTML form

$username = $_POST['author'];

$comment = $_POST['commentcontent'];

$postname = $_POST['postname'];

//Create a PHP array to insert into MongoDB

$insertcomment = ['author' => $username, 'comment' => $comment, 'postname' => $postname];

//Make the insert query / connection - the if / else just catches an error

if ($postcomment = $col->insertOne($insertcomment)){

        echo "<h3>Comment added to $postname. </h3>";

}

else { echo "<h3>Error occured while adding that comment. Please contact your IT administrator.</h3>"; }

I also wanted to create a hidden form so that it only appears when a user clicks 'ADD COMMENT'. Initially I was thinking using Javascript and passing an innerHTML call would work. It does for the action, but because the comments need to collect some hidden data (i.e. the post title, the logged in user, etc) in PHP variables, the hidden variables need to exist in the PHP code before the Javascript action takes place. 

Explanation: PHP is a server side language meaning all the actions are requests to the server on page load. If the page loaded, but the PHP variables are not present during page load, the script won't know about them. Javascript is a run-time in the web browser itself. This makes it good for these on page actions - like <onclick='dothisfunction()'>. However, passing additional HTML after the page loaded will omit the variables we need.

It turns out that Javascript has styling properties as well. What they do is allow for CSS changes to be applied to specific elements identified by the 'id' tag.  What we can do is rather than pass new HTML code to the page - which causes issues with the PHP variables needed - we can more simply change the fields from 'hidden' to 'visible'. This way the PHP variables are known to the script, but the same visual result of handling a pop up can be achieved. 

In code - HTML with PHP variables - called using echo in PHP

<button onclick='addcomment()'>ADD COMMENT</button><br><br>

<div id='AddComment' style='visibility: hidden;'>

<form method='post' action='submitcomment.php' id='insertComment'>

<textarea class='giantinput' name='commentcontent' placeholder='Add a comment'></textarea>

<input type='hidden' name='author' value='$loginuser'>

<input type='hidden' name='postname' value='$postname'>

<br><br><input type='submit' form='insertComment' value='Submit'></form>

</div>

In code - JS

function addcomment() {
    var commentform = document.getElementById('AddComment');
    
     if (commentform.style.visibility === 'hidden') {
        commentform.style.visibility = 'visible';
     }
    
     else { commentform.style.visibility = 'hidden'; }
 }

The above is fairly basic as an example implementation. For better accuracy, it may be the case that the HTML form for the comments needs to collect more than just the post title or name, but also say the post author, the date, or better the object ID to ensure if there are say multiple posts with the same name all the comments do not get pulled into each post. 

Just wanted to share a bit of code and discovery using PHP and Javascript hand-in-hand to create a useful layout. Hope it helps. 

Full source code and Docker Compose to install is located on GitHub.

 

Creating a web application with a MongoDB backend and Docker


This is a bit of a POC that turned into a project.

I was playing with MongoDB to create a front-end that would store data in a user friendly way. I didn't want to take on things like WordPress or others, and had an idea for a note taking application that could be on-prem, and put teams or catalogs first with grouping.

I think there is quite a bit more that could be done, like adding reminders/due dates to the posts/notes and adding more management to groups so new authors can add more people to a project/group. For now this is being used to demonstrate the capabilities of PHP with MongoDB.

A killer feature in MongoDB is the ability for it to not need to be primed in anyway. This feature allows for this app install using Docker to exist. In a traditional/relational database a user needs to setup the database and table structure in order for data to be inserted. With NoSQL/MongoDB you can just point an app at the DB and with the correct credentials start adding and editing a whole DB in the service itself. This is what I do in the initial login screen. I check if the DB and admin exist, and if not, they get automatically populated so a user on a completely fresh install can just start using the application. 

Currently this application is far from perfect, but I hope it helps users get an idea of what an be done using PHP, HTML, CSS, and MongoDB together. I also hope it can be useful, and if anyone requires additional assistance, please feel free to leave comments on the GitHub page. I am not at the caliber of a professional open source developer, and have limited time, but I am interested in the feedback, and willing to assist as I can to further promote usage of the project.

I hope this can be a useful project either for internal team collaboration or simply as reference code for other users. The code is published with the permissible Apache 2.0 license (same as Apache and MongoDB that it builds off).

Notes:

Source code is here: https://github.com/JoeMrCoffee/OurNoteOrganizer

A word on TinyMCE

TinyMCE is an external text editor which is used to help enhance the ease for writing and editing posts. It is an external tool that requires connectivity to external networks in order to function. For environments that do not have external Internet connectivity a standard 'textarea' without rich formatting is employed.

As this project is made to be hosted on any on-prem environment, there is no TinyMCE API key provided or registered. Users can create their own keys based on their domains and needs. To remove the notification about getting started, users can follow the quick steps, create their own API key, and add it to line 8 of the newpost.php file.

More information on TinyMCE and getting started:

https://www.tiny.cloud/

https://www.tiny.cloud/docs/quick-start/


Getting started with PHP and MongoDB

 

This post and video delve into the world of schemaless, NoSQL databases. NoSQL databases are powerful and interesting ways of storing data at scale. Because they do not have a traditional table that dictates what kind of data needs to be written, NoSQL databases, like MongoDB, can accept data much more easily. There is also the benefit that, at scale, a cluster of multiple nodes can be hosting a common database and collection where as a traditional database cannot scale-out horizontally. 

In cloud computing, NoSQL databases are what drive the likes of Amazon, Google, Facebook and more. 

In order to learn more about them I wanted to try and replicate what I know on PHP and MySQL (a schema or relational database), and apply it to PHP with MongoDB. I did struggle a bit because of the way I was building the container and my lack of familiarity with the way Composer works. As such I thought I'd share my progress and provide the docker-compose file along with a run through of how to get it setup and running. 

The Dockerfile and Docker Compose script are located on my GitHub with no license and anyone can feel free to use the repository to quickly bring up and test a LAMP stack using MongoDB instead of MySQL or MariaDB. Just git clone, and run docker-compose up from the directory and it should build everything. 

Also included in the repo is a very simple HTML form that will write a Name and Age to the MongoDB instance. These two web pages are essentially just offered as a reference for how to connect and get started. 

Docker Compose source: https://github.com/JoeMrCoffee/MongoLAMP

Additional references that I found helpful:

Official documentation on using PHP with MongoDB:
https://docs.mongodb.com/drivers/php/

Official Docker image for MongoDB and Mongo-Express:
https://hub.docker.com/_/mongo
(This was the base for the docker compose minus the Apache PHP image)

Another great tutorial which is worth a look as well.
https://www.javatpoint.com/php-mongodb