Running Advanced MongoDB Queries In TypeORM
Tags: node, database, mongodb, typescript
Published: 2024-06-12 00:22:17

TypeORM is a Javascript/Typescript ORM that works well with SQL databases and MongoDB, which is built to run in the browser, on the server aka Node.JS, Expo, and every single execution context that utilizes Javascript. TypeORM has excellent support for Typescript while allowing newbies to use it with Javascript.

TypeORM sits as a layer on top of our application and allows us to build our application using Object-oriented programming principles when interacting with our data you can check [the documentation]() to get more information about what TypeORM is. In today's post, we will go over how we can run some complex/advanced queries with TypeORM while working with MongoDB as our Database, and as such we will cover the following;

- Find Where Object property is equal to value 
- Find where  the field is in an array
- Find where value is a regexp
- Find where field A and field B is equal to a value
- Find where field A is equal to value or field B is equal to another value
- Paginating your queries.

### Find where object property is equal to a value

Let's say we have an Entity with the following structure 

```typescript
@Entity()
class User {
  @Column()
  first_name: string;
  @Column()
  last_name: string;
  @Column()
  address: string;
  @Column()
  standIn: {name: string;phone: string};
  @Column()
  roles: string[]
}
```

Let's say we want to fetch all the users who have a standIn with the name of John. This is a simple query to run, so we would write the query as  thus;

```typescript
import {AppDataSource } from '../app-data-source';
import {User} from '../entity/user';

const getUsersByStandIn = (standIn) => {
  return AppDataSource.mongoManager.find(User, {
    where: {
      "standIn.name": {$eq: standIn}
    }
  })
}
```

### Find where  the field is in an array

Let's say we want to run a query to get all the users with a certain role, say all the contractors.

```typescript
const getUserByPrevillage = (role) => {
  return AppDataSource.mongoManager.find(User, {
    where: {
      role: {
        $in: [previllage]
      }
    }
  })
}
```

### Running Regular Expression Checks

Sometimes we might want to run a regular expression check, say we want to find a user by their street address, however, we are not sure that the input string will be the complete address, the user might only enter their street Name or house number so this is what the query will look like;

```typescript
const findUserByAddress = (address) => {
  const regexp = new RegExp(address);
  return AppDataSource.mongoManager.find(User, {
    where: {address}
  })
}
```
And that's all it takes to run regular expression checks.

### Find where field A and field B is equal to a value

Sometimes we might want to run a query where we check that a particular field is equal to a value and another field is equal to another value, say we want to get a user by their email and phone number, the query we will write will look like this;

```typescript
const findUserByEmailAndPhone = (email, phone) => {
  return AppDataSource.mongoManager.find(User, {
    where: {
      email: {$eq: email},
      $and: [{phone: {$eq: phone }}]
    }
  })
}
```

### Find where field A is equal to value or field B is equal to another value

There are also scenarios where we want to check that a field is equal to a value or another field is equal to another value, say we want to fetch a user by their email or phone number, and the query for such an operation would look like this;

```typescript
const findUserByEmailOrPhone = (email, phone) => {
  return AppDataSource.mongoManager.find(User, {
    where: { 
      email: {$eq: email },
      $or: [{phone: {$eq: phone }}]
      },
  })
}
```

### Paginating your queries.

Lastly, let's look at how we can paginate our queries, this is very important for most applications because fetching all the documents in a collection might be computationally expensive and as such we will need to reduce the amount of data we are trying to retrieve at each point in time. This is my approach to pagination;

```typescript
const getUsers = (limit = 5, page = 1) => {
  return AppDataSource.mongoManager.find(User, {
    take: limit,
    skip: (page - 1) * limit
  })
}
```
This is a very simple but very powerful approach, as it handles both forward-tracking and backward-tracking. That's going to be it for this post, what are your thoughts on the queries we addressed, do you have a different way of doing things, I would gladly appreciate your feedback and your experience working with TypeORM and MongoDB. Use the comment section to express your thoughts and I hope you found this useful.