# Python MongoDB programming

MongoDB through outgoing connections - inserting, finding, updating and aggregating documents with pymongo.

Create an outgoing MongoDB connection in Dashboard and everything that MongoDB [offers](https://www.mongodb.com) will be available to your services via the underlying [pymongo](https://pymongo.readthedocs.io) library, as in the examples below.

## Creating a connection {#creating-a-connection}

In Dashboard, go to Connections -> NoSQL -> MongoDB and click Create a new outgoing MongoDB connection.

Fill in the form:

- Name - any name of your choice
- Server list - one `host:port` entry per line, e.g. a single `localhost:27017` line or several lines when connecting to a replica set
- Username and password - credentials to authenticate with, the auth source defaults to `admin`
- Replica set - optional, the name of the replica set to require

The TLS section lets you connect to servers that require encrypted connections - turn the TLS checkbox on and point the CA certificates file to the PEM certificate of the authority that signed the server's certificate. For mutual TLS, add a combined client certificate and private key PEM file too.

After the connection is created, click Ping to confirm that Zato can reach the server.

## Inserting documents {#inserting-documents}

In your services, look up the connection by name with `self.mongodb` - what you get back is a pymongo client, so databases and collections are accessed the way pymongo does it.

```python
# -*- coding: utf-8 -*-

# Zato
from zato.server.service import Service

class MyService(Service):

    def handle(self):

        # Get a client by the connection's name
        conn = self.mongodb['My MongoDB Connection']

        # Pick a database and a collection
        db = conn['my_database']
        orders = db['orders']

        # Insert a document
        result = orders.insert_one({'order_id': 123, 'status': 'ready'})

        self.logger.info('Inserted: %s', result.inserted_id)
```

## Finding documents {#finding-documents}

```python
# -*- coding: utf-8 -*-

# Zato
from zato.server.service import Service

class MyService(Service):

    def handle(self):
        conn = self.mongodb['My MongoDB Connection']
        orders = conn['my_database']['orders']

        # Find one document
        order = orders.find_one({'order_id': 123})
        self.logger.info('Order: %s', order)

        # Find all documents matching a query
        for item in orders.find({'status': 'ready'}):
            self.logger.info('Ready: %s', item)
```

## Updating and deleting {#updating-and-deleting}

```python
# -*- coding: utf-8 -*-

# Zato
from zato.server.service import Service

class MyService(Service):

    def handle(self):
        conn = self.mongodb['My MongoDB Connection']
        orders = conn['my_database']['orders']

        # Update a document
        orders.update_one({'order_id': 123}, {'$set': {'status': 'shipped'}})

        # Delete a document
        orders.delete_one({'order_id': 123})
```

## Aggregations {#aggregations}

The full aggregation pipeline is available too.

```python
# -*- coding: utf-8 -*-

# Zato
from zato.server.service import Service

class MyService(Service):

    def handle(self):
        conn = self.mongodb['My MongoDB Connection']
        orders = conn['my_database']['orders']

        # Count orders per status
        pipeline = [
            {'$group': {'_id': '$status', 'count': {'$sum': 1}}},
            {'$sort': {'count': -1}},
        ]

        for row in orders.aggregate(pipeline):
            self.logger.info('%s: %s', row['_id'], row['count'])
```

## Pinging from a service {#pinging-from-a-service}

```python
# -*- coding: utf-8 -*-

# Zato
from zato.server.service import Service

class MyService(Service):

    def handle(self):
        conn = self.mongodb['My MongoDB Connection']

        # The same command that the Dashboard's Ping link runs
        conn.admin.command('ping')

        self.logger.info('MongoDB is reachable')
```

## Learn more {#learn-more}

- [Development documentation](https://zato.io/docs/dev/) - The complete reference for writing services
- [Requests and responses](https://zato.io/docs/dev/request-response/) - What a service receives, what it returns and how both are structured
- [Integration examples](https://zato.io/docs/dev/examples/) - Ready-made code for the systems you are likely to connect to
- [IDE and debugging](https://zato.io/docs/dev/ide/) - Write services in the Dashboard or in your own editor
- [Data models](https://zato.io/docs/dev/model/) - Declare inputs and outputs and have them validated for you
- [In-depth API tutorial](https://zato.io/tutorials/main/01.html) - The full platform tutorial, from installation to production patterns
