Mongo DB 기본쿼리

MongoDB CRUD Operation

Mongo DB는 Create, Read, Update, Delete Operation을 제공합니다.

DDL SQL vs Mongo DB

create_sql_vs_mongo

create_sql_vs_mongo_2

Create Operations

Create, Insert Operation은 컬렉션(Collection)에 도큐먼트(Documents)를 삽입합니다.
만약 컬렉션이 아직 존재하지 않는다면, 도큐먼트 삽입과 동시에 컬렉션이 생성됩니다.

Mongo DB는 아래와 같은 도큐먼트 삽입을 위한 메서드를 제공합니다.

  • db.collection.insertOne() (collection 자리에 실제 collection명을 기재)
  • db.collection.insertMany()

모든 Mongo DB의 삽입 연산은 단일 컬렉션을 대상으로 하며, 모든 쓰기 작업은 단일 도큐먼트에 대해 원자적입니다.

insertOne

Insert SQL vs Mongo DB Insert

insert_sql_vs_mongo

Read Operations

읽기 작업(Read Operations)는 컬렉션에서 도큐먼트(Documents)를 검색합니다. (컬렉션을 쿼리하여 문서를 조회)
Mongo DB는 아래와 같은 도큐먼트 조회를 위한 메서드를 제공합니다.

  • db.collection.find() (collection 자리에 실제 collection명을 기재)

Mongo DB 쿼리 간 filter와 조건을 통해 특정한 도큐먼트를 조회할 수 있습니다.
read-query

위의 쿼리는 SQL로 표현한다면 아래와 같습니다.

1
2
3
4
SELECT name, address
FROM users
WHERE age > 18
LIMIT 5

Select SQL vs Mongo DB Read

read_sql_vs_mongo

read_sql_vs_mongo2

read_sql_vs_mongo3

Update Operations

수정 작업 (Update Operations)은 컬렉션 내에 존재하는 도큐먼트를 수정합니다.
Mongo DB는 컬렉션 내의 도큐먼트 수정을 위해 아래와 같은 메서드를 제공합니다.

  • db.collection.updateOne() (collection 자리에 실제 collection명을 기재)
  • db.collection.updateMany()
  • db.collection.replaceOne()

Mongo DB에서는 단일 컬렉션을 대상으로 update operation을 지원합니다.
Mongo DB 내의 모든 쓰기 작업은 단일 도큐먼트 레벨에서 원자적입니다.

update-query

Update SQL vs Mongo DB Update

update_sql_vs_mongo

Delete Operations

삭제 작업 (Delete Operations)은 컬렉션 내의 도큐먼트를 삭제합니다.
Mongo DB는 컬렉션 내의 도큐먼트 삭제를 위해 아래와 같은 메서드를 제공합니다.

  • db.collection.deleteOne() (collection 자리에 실제 collection명을 기재)
  • db.collection.deleteMany()

Mongo DB에서의 삭제 작업은 단일 Collection을 대상으로 합니다.
Mongo DB 내의 모든 쓰기 작업은 단일 도큐먼트 레벨에서 원자적입니다.

특정 filter나 조건을 주어 특정한 도큐먼트를 삭제 할 수 있습니다. (Read Operation과 비슷)

delete-query

Delete SQL vs Mongo DB Delete

delete_sql_vs_mongo

Spring Data MongoDB를 이용한 CRUD

Spring에서 Mongo DB 연동 시에는 spring-data에서 제공하는 spring-data-mongodb를 이용하는게 가장 편리합니다.

Maven 설정

spring-data-mongodb dependency 추가

1
2
3
4
5
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>

Mongo DB QueryDsl Dependency 추가

1
2
3
4
5
6
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-mongodb</artifactId>
<version>4.2.1</version>
</dependency>

Document class Build Plugin 설정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<id>jpa-processor</id>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
<execution>
<id>mongodb-processor</id>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>

Entity 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* @Author by Carrey on 2019-02-20
* Employee Test
*/
@Setter
@Getter
@AllArgsConstructor
@Document(collection = "employee")
public class Employee {

@Id
private int id;
private String ename;
private String job;
private Integer mgrId;
@Indexed
private LocalDate hiredate;
private long sal;
private Long commision;
@Indexed
private Integer deptId;
private String deptName;

public void raiseSalary(DoubleFunction<Long> raiseFormula) {
this.sal = raiseFormula.apply(this.sal);
}
}
  • @Document : Class가 Mongo DB Document라는 의미를 지정 (collection 속성에 collection 명 지정)
  • @Id : Document내의 ID지정 (_id 필드에 해당 값이 매핑)
    (주의! org.springframework.data.annotation.Id를 import 해야함)
  • JPA에서는 @Entity 클래스의 ID설정이 무조건 필요했지만, Mongo DB는 선택적으로 @Id지정 가능
    (@Id를 지정하지 않으면 도큐먼트에 ObjectId라는 키가 자동으로 생성됨)
  • @Indexed : Collection Index를 지정 (단일인덱스 여러개 지정가능)
    (복합 인덱스도 있으나 일단 기술하지 않음)

Repository 생성

1
2
3
4
5
/**
* @Author by Carrey on 2019-02-20
*/
public interface EmployeeMongoRepository extends MongoRepository<Employee, Integer> {
}

MongoRepository<T ,ID>에서 제공하는 메서드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
   /** CRUDRepository.saveAll */
@Override
<S extends T> List<S> saveAll(Iterable<S> entities);

/** CRUDRepository.findAll */
@Override
List<T> findAll();

/** CRUDRepository.findAll */
@Override
List<T> findAll(Sort sort);

<S extends T> S insert(S entity);

<S extends T> List<S> insert(Iterable<S> entities);

@Override
<S extends T> List<S> findAll(Example<S> example);

@Override
<S extends T> List<S> findAll(Example<S> example, Sort sort);

QueryDsl을 이용한 Read Operations

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Repository
public class EmployeeRepository extends QuerydslRepositorySupport {

@Autowired
private MongoTemplate mongoTemplate;

/**
* Creates a new {@link QuerydslRepositorySupport} for the given {@link MongoOperations}.
*
* @param operations must not be {@literal null}.
*/
public EmployeeRepository(MongoOperations operations) {
super(operations);
}

//2000$가 넘는 고액 연봉자 조회 쿼리
public List<Employee> getCoreEmployees() {

QEmployee qEmployee = QEmployee.employee;
List<Employee> coreEmployees = from(qEmployee).where(qEmployee.sal.gt(2000L))
.fetch();

return coreEmployees;
}
}
  • queryDsl 방식의 장점
    • Spring-data 패키지의 메서드를 그대로 쓰기 때문에 JPA에서 사용하던 쿼리와 똑같다.
  • queryDsl 방식의 단점
    • @Document class를 mongodb-processor를 이용하여 Q클래스로 만들어야 한다.
    • Aggregation pipeline을 지원하지 않는다. (가장 큰 단점)

참고