# MongoDB - [MongoDB support](#mongodb-support) - [Defining entities and columns](#defining-entities-and-columns) - [Defining subdocuments (embed documents)](#defining-subdocuments-embed-documents) - [Using `MongoEntityManager` and `MongoRepository`](#using-mongoentitymanager-and-mongorepository) ## MongoDB support TypeORM has basic MongoDB support. Most of TypeORM functionality is RDBMS-specific, this page contains all MongoDB-specific functionality documentation. ## Defining entities and columns Defining entities and columns is almost the same as in relational databases, the main difference is that you must use `@ObjectIdColumn` instead of `@PrimaryColumn` or `@PrimaryGeneratedColumn`. Simple entity example: ```typescript import { Entity, ObjectId, ObjectIdColumn, Column } from "typeorm" @Entity() export class User { @ObjectIdColumn() _id: ObjectId @Column() firstName: string @Column() lastName: string } ``` And this is how you bootstrap the app: ```typescript import { DataSource } from "typeorm" const myDataSource = new DataSource({ type: "mongodb", host: "localhost", port: 27017, database: "test", }) ``` ## Defining subdocuments (embed documents) Since MongoDB stores objects and objects inside objects (or documents inside documents) you can do the same in TypeORM: ```typescript import { Entity, ObjectId, ObjectIdColumn, Column } from "typeorm" export class Profile { @Column() about: string @Column() education: string @Column() career: string } ``` ```typescript import { Entity, ObjectId, ObjectIdColumn, Column } from "typeorm" export class Photo { @Column() url: string @Column() description: string @Column() size: number constructor(url: string, description: string, size: number) { this.url = url this.description = description this.size = size } } ``` ```typescript import { Entity, ObjectId, ObjectIdColumn, Column } from "typeorm" @Entity() export class User { @ObjectIdColumn() id: ObjectId @Column() firstName: string @Column() lastName: string @Column((type) => Profile) profile: Profile @Column((type) => Photo) photos: Photo[] } ``` If you save this entity: ```typescript import { getMongoManager } from "typeorm" const user = new User() user.firstName = "Timber" user.lastName = "Saw" user.profile = new Profile() user.profile.about = "About Trees and Me" user.profile.education = "Tree School" user.profile.career = "Lumberjack" user.photos = [ new Photo("me-and-trees.jpg", "Me and Trees", 100), new Photo("me-and-chakram.jpg", "Me and Chakram", 200), ] const manager = getMongoManager() await manager.save(user) ``` Following document will be saved in the database: ```json { "firstName": "Timber", "lastName": "Saw", "profile": { "about": "About Trees and Me", "education": "Tree School", "career": "Lumberjack" }, "photos": [ { "url": "me-and-trees.jpg", "description": "Me and Trees", "size": 100 }, { "url": "me-and-chakram.jpg", "description": "Me and Chakram", "size": 200 } ] } ``` ## Using `MongoEntityManager` and `MongoRepository` You can use the majority of methods inside the `EntityManager` (except for RDBMS-specific, like `query` and `transaction`). For example: ```typescript const timber = await myDataSource.manager.findOneBy(User, { firstName: "Timber", lastName: "Saw", }) ``` For MongoDB there is also a separate `MongoEntityManager` which extends `EntityManager`. ```typescript const timber = await myDataSource.manager.findOneBy(User, { firstName: "Timber", lastName: "Saw", }) ``` Just like separate like `MongoEntityManager` there is a `MongoRepository` with extended `Repository`: ```typescript const timber = await myDataSource.getMongoRepository(User).findOneBy({ firstName: "Timber", lastName: "Saw", }) ``` Use Advanced options in find(): Equal: ```typescript const timber = await myDataSource.getMongoRepository(User).find({ where: { firstName: { $eq: "Timber" }, }, }) ``` LessThan: ```typescript const timber = await myDataSource.getMongoRepository(User).find({ where: { age: { $lt: 60 }, }, }) ``` In: ```typescript const timber = await myDataSource.getMongoRepository(User).find({ where: { firstName: { $in: ["Timber", "Zhang"] }, }, }) ``` Not in: ```typescript const timber = await myDataSource.getMongoRepository(User).find({ where: { firstName: { $not: { $in: ["Timber", "Zhang"] } }, }, }) ``` Or: ```typescript const timber = await myDataSource.getMongoRepository(User).find({ where: { $or: [{ firstName: "Timber" }, { firstName: "Zhang" }], }, }) ``` Querying subdocuments ```typescript const users = await myDataSource.getMongoRepository(User).find({ where: { "profile.education": { $eq: "Tree School" }, }, }) ``` Querying Array of subdocuments ```typescript // Query users with photos of size less than 500 const users = await myDataSource.getMongoRepository(User).find({ where: { "photos.size": { $lt: 500 }, }, }) ``` Both `MongoEntityManager` and `MongoRepository` contain lot of useful MongoDB-specific methods: #### `createCursor` Creates a cursor for a query that can be used to iterate over results from MongoDB. #### `createEntityCursor` Creates a cursor for a query that can be used to iterate over results from MongoDB. This returns a modified version of the cursor that transforms each result into Entity models. #### `aggregate` Execute an aggregation framework pipeline against the collection. #### `bulkWrite` Perform a bulkWrite operation without a fluent API. #### `count` Count number of matching documents in the db to a query. ### `countDocuments` Count number of matching documents in the db to a query. #### `createCollectionIndex` Creates an index on the db and collection. #### `createCollectionIndexes` Creates multiple indexes in the collection, this method is only supported in MongoDB 2.6 or higher. Earlier version of MongoDB will throw a command not supported error. Index specifications are defined at http://docs.mongodb.org/manual/reference/command/createIndexes/. #### `deleteMany` Delete multiple documents on MongoDB. #### `deleteOne` Delete a document on MongoDB. #### `distinct` The distinct command returns a list of distinct values for the given key across a collection. #### `dropCollectionIndex` Drops an index from this collection. #### `dropCollectionIndexes` Drops all indexes from the collection. #### `findOneAndDelete` Find a document and delete it in one atomic operation, requires a write lock for the duration of the operation. #### `findOneAndReplace` Find a document and replace it in one atomic operation, requires a write lock for the duration of the operation. #### `findOneAndUpdate` Find a document and update it in one atomic operation, requires a write lock for the duration of the operation. #### `geoHaystackSearch` Execute a geo search using a geo haystack index on a collection. #### `geoNear` Execute the geoNear command to search for items in the collection. #### `group` Run a group command across a collection. #### `collectionIndexes` Retrieve all the indexes on the collection. #### `collectionIndexExists` Retrieve if an index exists on the collection #### `collectionIndexInformation` Retrieves this collections index info. #### `initializeOrderedBulkOp` Initiate an In order bulk write operation, operations will be serially executed in the order they are added, creating a new operation for each switch in types. #### `initializeUnorderedBulkOp` Initiate a Out of order batch write operation. All operations will be buffered into insert/update/remove commands executed out of order. #### `insertMany` Inserts an array of documents into MongoDB. #### `insertOne` Inserts a single document into MongoDB. #### `isCapped` Returns if the collection is a capped collection. #### `listCollectionIndexes` Get the list of all indexes information for the collection. #### `parallelCollectionScan` Return N number of parallel cursors for a collection allowing parallel reading of entire collection. There are no ordering guarantees for returned results #### `reIndex` Reindex all indexes on the collection Warning: reIndex is a blocking operation (indexes are rebuilt in the foreground) and will be slow for large collections. #### `rename` Changes the name of an existing collection. #### `replaceOne` Replace a document on MongoDB. #### `stats` Get all the collection statistics. #### `updateMany` Updates multiple documents within the collection based on the filter. #### `updateOne` Updates a single document within the collection based on the filter.