Monthly Archives: May 2021

Error Inserting Records into a MongoDb Database

In my recent posts I’ve been trying to learn a little about MongoDB, and the API. Whilst trying to insert data into a MongoDB database, I got an error; and, since I couldn’t really find anything about it on the internet, I thought I’d add something.

Here’s the code that I initially (and incorrectly) tried to use to insert a record:

            var newData = new MyData()
            {
                SomeDate = myDate,
                Text = "hello"
            };
            var document = BsonDocument.Create(newData);

            var collection = _db.GetCollection<BsonDocument>("testcollection");
            await collection.InsertOneAsync(document);

            return newData.Id.ToString();

If you execute the code above, you’ll get the following error:

System.ArgumentException: ‘.NET type MyApp.Entities.MyData cannot be mapped to BsonType.Document. ‘

In fact, the issue is caused because you need to convert the data into a BSON document first; like so:

            var newData = new MyData()
            {
                SomeDate = myDate,
                Text = "hello"
            };
            var bson = newData.ToBsonDocument();
            var document = BsonDocument.Create(bson);            

            var collection = _db.GetCollection<BsonDocument>("testcollection");
            await collection.InsertOneAsync(document);

            return newData.Id.ToString();

Creating a C# Client, and Listing, and Adding Data in MongoDB

In this previous post I wrote about how you can install MongoDB, and use the built in clients to interrogate the data. In this post I’ll cover setting up a simple C# client to interrogate the database.

Bring in a NuGet Package

As with many integrations in the last 10 years, 90% of the job is installing the right NuGet package:

Install-Package MongoDB.Driver

Once that’s installed, you should have access to the SDK. You’ll need the following using statement:

using MongoDB.Driver;

Connecting to the MonoDB Instance

It actually took me a while to work out the correct format here; for the default instance, you can simply use this for the connection string:

mongodb://localhost:27017

So to connect to the DB, you would use this:

MongoClient dbClient = new MongoClient("mongodb://localhost:27017");
var db = dbClient.GetDatabase("testdb");

See the referenced previous post if you’re interested where testdb came from.

Collections

As we saw in the previous post, Mongo works around the concept of collections – it’s roughly analogous to a table. The list the collections:

MongoClient dbClient = new MongoClient("mongodb://localhost:27017");
var db = dbClient.GetDatabase("testdb");

var collections = await db.ListCollectionsAsync();
            
foreach (var col in collections.ToList())
{
    Console.WriteLine(col.ToString());
}

Let’s see what inserting data would look like.

Inserting Data

In fact, inserting data is very straightforward. We need to introduce a new type here, called a BsonDocument. BSON is a Binary JSON document, and to all intents and purposes, it’s JSON; this means that you can create a document such as this:

            var document = new BsonDocument()
            {
                { "test", "test1" },
                { "test2", "test2" },
                { "test3", "test3" }
            };

Or, indeed, any valid JSON document.

To insert this into the DB, you would just call InsertOne:

            var collection = db.GetCollection<BsonDocument>("testcollection");
            await collection.InsertOneAsync(document);

You can insert many records by calling InsertMany:

            var documents = new List<BsonDocument>()
            {
                new BsonDocument()
                {
                    { "test", "test1" },
                    { "test2", "test2" },
                    { "test3", "test3" }
                },
                new BsonDocument()
                {
                    { "Date", DateTime.Now },
                    { "test2", 12 },
                    { "test3", "hello" }
                }
            };

            var collection = db.GetCollection<BsonDocument>("testcollection");
            await collection.InsertManyAsync(documents);

References

https://www.mongodb.com/blog/post/quick-start-c-sharp-and-mongodb-starting-and-setup

Installing and Running MongoDB from Scratch

I’m relatively new to Mongo, but I’ve decided to use it for a recent project, mainly because it writes quickly. I wanted to install and run it locally; however, most of the tutorials for Mongo push Atlas pretty heavily, so I thought it might be worth creating a post on installing and running Mongo from scratch. Most of what’s here is a duplication of what you can find in the official docs.

Download

Start by downloading Mongo from here.

You’re then given some options during the installation. If you decide to change any of the default directories, then make a note of what you change them to; otherwise just accept the defaults:

This process will install MongoDb Compass by default – this is Mongo’s equivalent of SQL Server Management Studio, or MySQL’s SQL Workbench.

Running the Service

Mongo will install a Windows Service by default (well, if you look closely at the screenshot above, you’ll see that it’s pretty easy to stop it doing this), and you can just connect to this; however, you can remove that service (just go into Windows -> Services and remove it).

If you choose to keep the default installation then skip down to the Compass step.

In order to run Mongo yourself, you’ll need to run a command window, and navigate to the Mongo installation directory (typically C:\Program Files\MongoDB\Server\4.4\bin):

The key files here are:
– mongo.exe which is a mongo client
– mongod.exe which is the database service

The first thing to do is to start the DB Service:

.\mongod.exe –dbpath=”c:\tmp\mongodata”

This will use c:\tmp to store the data in.

Running the Client and Manipulating the Data

Now that the server is running, you can launch the client:

First, launch a command prompt as admin.

Next navigate to: C:\Program Files\MongoDB\Server\4.4\bin\

PS C:\Program Files\MongoDB\Server\4.4\bin> .\mongo.exe

This is a command line client. To create a new DB, just tell it to use a database that doesn’t exist:

> use testdb
switched to db testdb
> db.testcollection.insertOne({test: "test", test2: 1})
{
        "acknowledged" : true,
        "insertedId" : ObjectId("60830bfe34473a83b0fe56a6")
}
>

Here, we’ve inserted an object into the database; we can view that object by using something like the following:

> db.testcollection.find()
{ "_id" : ObjectId("60830bfe34473a83b0fe56a6"), "test" : "test", "test2" : 1 }
>

Finally, we can do the same thing, but in a GUI, called Compass.

Compass

After launching Compass for the first time, select New Connection, and then Fill in connection fields individually:

The following will work if you’ve just installed the default (as above) and made no config changes:

We can now browse the data that we inserted earlier:

References

https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/

Terraform – Autoscale an App Service

I’ve recently been writing about Terraform – mainly because I’m learning it from scratch, and playing about with tech and then writing about it is basically my way of learning.

In this post, I’m going to build on this previous post on creating an App Service, by adding a Scale Out feature to it.

This is the App Service that we created in the referenced post:

In the image, you’ll see Scale Out. Note that it says (App Service Plan): in fact, this is just a link to the App Service Plan Scale Out. We can access it from here – let’s see what that looks like:

As we can see, there’s a single instance of the App Service, and it’s managed manually. What we’re going to do is change that so that the App Service is auto-scaled.

The Terraform script here is broadly taken from the example here. However, that applies to a VM Scale Set, whereas we’re applying it to an App Service Plan.

resource "azurerm_monitor_autoscale_setting" "example" {
  name                = "myAutoscaleSetting"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  target_resource_id  = azurerm_app_service_plan.app-service-plan.id
  profile {
    name = "default"
    capacity {
      default = 1
      minimum = 1
      maximum = 10
    }
    rule {
      metric_trigger {
        metric_name        = "CpuPercentage"
        metric_resource_id = azurerm_app_service_plan.app-service-plan.id
        time_grain         = "PT1M"
        statistic          = "Average"
        time_window        = "PT5M"
        time_aggregation   = "Average"
        operator           = "GreaterThan"
        threshold          = 90
      }
      scale_action {
        direction = "Increase"
        type      = "ChangeCount"
        value     = "1"
        cooldown  = "PT1M"
      }
    }
    rule {
      metric_trigger {
        metric_name        = "CpuPercentage"
        metric_resource_id = azurerm_app_service_plan.app-service-plan.id
        time_grain         = "PT1M"
        statistic          = "Average"
        time_window        = "PT5M"
        time_aggregation   = "Average"
        operator           = "LessThan"
        threshold          = 10
      }
      scale_action {
        direction = "Decrease"
        type      = "ChangeCount"
        value     = "1"
        cooldown  = "PT1M"
      }
    }
  }  
}

Some key points:

– The example uses “Percentage CPU”, whereas for an App Service, this gets switched to CpuPercentage.
– The resource IDs that are referred to are that of the App Service Plan.

Finally, if we apply that, we can see the autoscale:

References

https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/monitor_autoscale_setting

https://stackoverflow.com/questions/58657096/error-creating-auto-scaling-rule-for-app-service-using-terraform-in-azure

Getting Started with Gatsby

Although I’ve used React before, Gatsby was quite new to me. This post was born from the creation of this website. We needed something that would let us create a nice looking site very quickly. Gatsby looked like it might be the answer.

Installation

To install gatsby, you can do so from npm:

npm Install -g gatsby-cli

Creating a Project

You can start from scratch, but they have a number of template projects here for you to clone.

Running

Once you’ve cloned the template, you can run it:

gatsby develop

You’ll need to run this from whichever directory you have package.json in (typically the root directory).

That will run your project locally (usually on 8080).

Deploying

Once you’re happy that this works, you can deploy the site using the build command:

gatsby build

This will create a /public folder, which is, effectively, your website – you can now just copy this to wherever you’re serving the site from and you’re good to go.