# Intermediate Mongo

## Lesson Objectives

Let's go into a few more complex examples of how Mongo can be used. We'll cover the following:

1. Using intermediate find operators
2. Explaining update operators
3. Explaining upserts
4. Explaining multiple updates

## Use intermediate find operators

To find all the documents in our collection that have a weight property greater than 700, we run:

```javascript
db.employees.find({
   weight: { $gt : 700 }
});
```

There are several comparisons we can perform

| Syntax  | Meaning                                                      |
| ------- | ------------------------------------------------------------ |
| $lt     | less than                                                    |
| $lte    | less than or equal to                                        |
| $gt     | greater than                                                 |
| $gte    | greater than or equal to                                     |
| $ne     | not equal to                                                 |
| $exists | does the property exist on an object -- either true or false |
| $in     | does the value exist within the given array                  |

If the field is an array, you can search for a match within that array

```javascript
db.employees.find({ loves: 'energon' });
```

If the object you pass into `find()` has more than one attribute, it will return documents that match both criteria. This is called an AND statement (like &&)

```javascript
db.employees.find({
   gender: 'm',
   weight: { $gt: 700 }
});
```

To find all documents that match at least one of a set of criteria, use an OR statement (like ||)

```javascript
db.employees.find({
   $or: [
      { loves: 'apple'},
      { weight: { $lt: 500 }
   ]
});
```

To find documents that have a value that matches multiple criteria, pass an object that contains both tests. This is similar to an AND (&&), but for one property. If you try to do a normal AND statement, but use the same property, twice it won't work.

```javascript
db.employees.find({
   salary: {
      $gte : 80,
      $lte : 165
   }
});
```

## Explain intermediate update operators

We can increase a specific value

```javascript
db.employees.update({ name: 'Pilot'}, { 
   $inc: { salary: -2 }
});
```

Multiple a value

```javascript
db.employees.update({ name: 'Pilot'}, {
   $mul: { salary: (1/2) }
});
```

Push a value onto an array

```javascript
db.employees.update({ name: 'Aurora' }, {
   $push: { loves: 'sugar' }
});
```

Pop a value off an array

```javascript
db.employees.update({ name: 'Aurora' }, {
   $pop: { loves: 1 }
});
```

Remove a property altogether

```javascript
db.employees.update({ name: 'Aurora' }, {
   $unset: { loves: '' }
});
```

Rename a field

```javascript
db.employees.update({ name: 'Aurora' }, {
   $rename: { wrong_field_name : 'correct_field_name' }
});
```

For more operators, look here: <http://docs.mongodb.org/manual/reference/operator/update/#update-operators>

## Explain upserts

Upserts will insert a value if it doesn't exist. If it does, it will update it.

Normal:

```javascript
db.hits.update({ page: 'employees' }, {
   $inc: { hits: 1 }
});

db.hits.find();
```

Upsert:

```javascript
db.hits.update({ page: 'employees' }, {
   $inc: { hits: 1 }
},
{
   upsert:true
});

db.hits.find();
```

Another Upset:

```js
db.hits.update({ page: 'employees' },{
   $inc: { hits: 1 }
},
{
   upsert:true
});

db.hits.find();
```

## Summary

MongoDB is quite versatile and gives the developer a lot more freedom than SQL. What would easily break a SQL database - like suddenly removing or renaming a column - are totally fine in a Mongo database!
