> For the complete documentation index, see [llms.txt](https://openai.gitbook.io/code-cheatsheets/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://openai.gitbook.io/code-cheatsheets/js/all/node/db/mongoose.md).

# Mongoose

```bash
yarn add mongoose
```

1. Connect mongoose as in setup
2. Create a model in ./models/somemodel.js
3. Import model in routes and use model fts

## Setup

```javascript
const mongoose = require('mongoose');

const mongoDB = 'mongodb://127.0.0.1/my_database';
mongoose.connect(mongoDB);
//usually mongoose uses pseudo promises, this tells it to use real ones
mongoose.Promise = global.Promise;

//Get the default connection
const db = mongoose.connection;
//Bind connection to error event (to get notification of connection errors)
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
```

## Defining Models

Models are defined using the Schema interface.

```javascript
const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const childSchema = new Schema({ name: 'string' });

//1. Define a schema
const TestSchema = new Schema({
  name: String,
  binary: Buffer,
  living: Boolean,
  updated: { type: Date, default: Date.now },
  age: { type: Number, min: 18, max: 65, required: true },
  mixed: Schema.Types.Mixed, //any type
  team_id: { type: Schema.Types.ObjectId, ref: "Team" }, //allows use of populate?
  array: [],
  ofString: [String], // You can also have an array of each of the other types too.
  nested: { stuff: { type: String, lowercase: true, trim: true } },
  drink: { //enum
    type: String,
    enum: ['Coffee', 'Tea']
  },
  children: [childSchema], // Array of subdocuments
  child: childSchema //Caveat: only single nested
});
});

//2. Compile model from schema
const Test = mongoose.model("Test", TestSchema);
//will use collection called Tests adding the s

module.exports = Test;
```

#### Schema [Types](http://mongoosejs.com/docs/schematypes.html)

* Can also have instance methods, static methods, and speciality queries

  **Virtual**

Fields that dont exist in db

```javascript
AuthorSchema
.virtual('url')
.get(function () {
  return '/catalog/author/' + this._id;
});
```

Can now do Author.name

## Using Models

#### Creating

```javascript
const SomeModel = require("../models/SomeModel.js");

const awesome_instance = new SomeModel({ name: 'awesome' });
const newInstance = await awesome_instance.save();
```

*Use mongoose.Types.ObjectId(uid) to convert string to objectID*

#### Querying

Use `.exec()` to give you a promise, make sure to have set `mongoose.Promise` in setup

```javascript
const allTests = await Test.find().exec();
const users = await User.find({ 'sport': 'Tennis' }, 'name age').exec();
const athletes = await Athlete.
  find().
  where('sport').equals('Tennis').
  where('age').gt(17).lt(50).
  limit(5).
  sort({ age: -1 }). //1 asc
  select('name age').
  exec();
//look at nested {token: id: {...}}
const user = await User.find({ "token.id": 1 });
```

* [`Model.deleteMany()`](https://mongoosejs.com/docs/api.html#model_Model.deleteMany)
* [`Model.deleteOne()`](https://mongoosejs.com/docs/api.html#model_Model.deleteOne)
* [`Model.find()`](https://mongoosejs.com/docs/api.html#model_Model.find) //Returns `[]`  if not found
* [`Model.findById()`](https://mongoosejs.com/docs/api.html#model_Model.findById) //basically fineOne
* [`Model.findByIdAndDelete()`](https://mongoosejs.com/docs/api.html#model_Model.findByIdAndDelete)
* [`Model.findByIdAndRemove()`](https://mongoosejs.com/docs/api.html#model_Model.findByIdAndRemove)
* [`Model.findByIdAndUpdate()`](https://mongoosejs.com/docs/api.html#model_Model.findByIdAndUpdate)
* [`Model.findOne()`](https://mongoosejs.com/docs/api.html#model_Model.findOne) //Returns `null` if not found
* [`Model.findOneAndDelete()`](https://mongoosejs.com/docs/api.html#model_Model.findOneAndDelete)
* [`Model.findOneAndRemove()`](https://mongoosejs.com/docs/api.html#model_Model.findOneAndRemove)
* [`Model.findOneAndReplace()`](https://mongoosejs.com/docs/api.html#model_Model.findOneAndReplace)
* [`Model.findOneAndUpdate()`](https://mongoosejs.com/docs/api.html#model_Model.findOneAndUpdate) //returns found documents
* [`Model.replaceOne()`](https://mongoosejs.com/docs/api.html#model_Model.replaceOne)
* [`Model.updateMany()`](https://mongoosejs.com/docs/api.html#model_Model.updateMany)
* [`Model.updateOne()`](https://mongoosejs.com/docs/api.html#model_Model.updateOne) //returns object with nModified being 0

#### Count

returns number >= 0

```javascript
const showCount = await Show.countDocuments({ _id: show_id });
const showExists = (await Show.countDocuments({ _id: show_id })) > 0;
```

## Advanced

### Model Instance Methods

```javascript
  // define a schema
  var animalSchema = new Schema({ name: String, type: String });

  // assign a function to the "methods" object of our animalSchema
  animalSchema.methods.findSimilarTypes = function(cb) {
    return this.model('Animal').find({ type: this.type }, cb);
  };
```

```
  var Animal = mongoose.model('Animal', animalSchema);
  var dog = new Animal({ type: 'dog' });

  dog.findSimilarTypes(function(err, dogs) {
    console.log(dogs); // woof
  });
```

### Upsert

```javascript
//create if doesn't exist yet too
const user = await User.findOneAndUpdate({ email: profile.email }, payload, {
  upsert: true,
  new: true, //return new user not old one
  setDefaultsOnInsert: true
}).exec();
```

### References

```javascript
const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const authorSchema = Schema({
  name    : String,
  stories : [{ type: Schema.Types.ObjectId, ref: 'Story' }] //model saved as
});
```

To get all stories authored, have to do a find of bob.\_id

```javascript
Story
.find({ author : bob._id })...
```

Can also fill in the field with the right model

```javascript
const story = await Story
.findOne({ title: 'Bob goes sledding' });;
await story.populate("author").execPopulate();
story.author.name;
```

#### Callback Style

Callback Style

```javascript
awesome_instance.save(function (err) {
  if (err) return handleError(err);
  // saved!
});

User.find({}, function(err, users) {});
// find all athletes who play tennis, selecting the 'name' and 'age' fields
Athlete.find({ 'sport': 'Tennis' }, 'name age', function (err, athletes) {
  if (err) return handleError(err);
  // 'athletes' contains the list of athletes that match the criteria.
})
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://openai.gitbook.io/code-cheatsheets/js/all/node/db/mongoose.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
