Back-End/MongoDB

[MongoDB] MQL 기초 4 - 배열과 내장 Document를 다루는 방법 1 (Read)

유자맛바나나 2024. 5. 31. 01:54

 

1. 내장 Document 조회 (Inner Document)

  • 내장 Document는 Document 안에 필드가 Document인 것을 말한다.

예시

db.sales.findOne() 조회 결과

{
	...
	customer : { gender:'M', age: 50, email:'hello@naver.com', satisfaction:5 }
	...
}
  • Document를 조회한 결과 customer 필드는 Document를 갖고 있다. 이를 내장 Document라고 한다

 

조회방법 1. 내장 Document 전체를 filter로 적용

내장 Document를 조회할 땐 filter에 해당 Document를 전부 명시해줘야 한다

즉, 위의 customer를 조회하려면 다음과 같이 MQL을 써야한다.

db.sales.findOne(
	{ customer : { gender:'M', age: 50, email:'hello@naver.com', satisfaction:5 } }
)

 

주의 : 내장 Document의 필드 순서가 다르면 조회가 되지 않는다

db.sales.findOne(
	{ customer : { age: 50, email:'hello@naver.com', satisfaction:5, gender:'M' } }
	# gender를 가장 뒤로 보냄
)
  • 위와 같이 필드 순서를 지키지 않으면 조회 결과는 null이다

 

조회방법 2. ‘.’을 이용해 특정 field를 filter로 적용

db.sales.findOne(
	{ "customer.gender": 'M' }
)

db.sales.findOne(
	{ "customer.age": {$lt: 20} }
)

 

2. Array field 다루기

2.1. Element의 index를 사용

db.inventory.find(
	{ "tags.0": 'blue' }
)
  • tags array에 0번째 index element가 ‘blue’ 인 document 조회

 

2.1. 한 개의 Element를 포함

db.inventory.find(
	{ tags: 'blue' }
)
  • tags array에 ‘blue’ 를 포함하는 document 조회

 

2.2. Element가 정확히 일치

db.inventory.find(
	{ tags: ['red', 'blank'] }
)
  • tags array에 정확히 ‘red’, ‘blank’ 두 개만 갖고, 순서도 red, blank인 document 조회

 

2.3. $all : 여러 개의 Element를 반드시 포함

db.inventory.find(
	{ tags: { $all: ['red', 'blank'] } }
)
  • tags array에 ‘red’, ‘blank’ 두 개를 순서 상관없이 포함하는 document 조회
  • red, blank 외에 다른 값을 가져도 결과에 포함

 

2.4. $in : 여러 개의 Element 중 한 개라도 포함

db.inventory.find(
	{ tags: { $in: ['red', 'blank'] } }
)
  • tags array에 ‘red’ 또는 ‘blank’ 가 포함된 document 조회

 

2.5. $size : array의 크기를 기준으로 조회

db.inventory.find(
	{ tags: { $size: 3 } }
)
  • tags array의 크기가 3인 document 조회

 

2.5. $gt : 특정 값 이상의 Element를 포함

db.inventory.find(
	{ dim_cm: {$gt: 15} }
)
  • dim_cm array에 15 이상 값이 포함된 document 조회

 

주의 2.6. $gt, $lt 동시 사용 : 두 개의 조건을 모두 만족하는 결과 조회

db.inventory.find(
	{ dim_cm: {$gt: 15, $lt: 20} }
)
  • dim_cm array에 15이상, 20이하인 값 둘 다 포함된 document 조회
  • 2.7의 $elemMatch를 사용하는 between 연산과 헷갈릴 수 있으므로 아래의 조회 결과를 참고하자

 

1) 포함될 수 있는 결과

{
	...
	dim_cm: [ 14, 21 ]
	...
}
  • 21은 14보다 크다. 따라서 $gt: 15 의 필터 조건은 true
  • 14는 20보다 작다. 따라서 $lt: 20 의 필터 조건은 true
  • 두 개의 조건 모두 true이므로 포함될 수 있다.

 

2) 포함될 수 없는 결과

{
	...
	dim_cm: [ 22.85, 30 ]
	...
}
  • 22.85, 30 모두 15 보다 크다. 따라서 $gt: 15 의 필터 조건은 true
  • 22.85, 30 모두 20 보다 작지 않다. 따라서 $lt: 20 의 필터 조건은 false
  • filter 조건인 {$gt: 15, $lt: 20}가 comma로 연결되어 있으므로 둘 중 하나라도 false일 경우 false이다. 따라서 위의 document는 포함될 수 없는 결과다

 

2.7. $elemMatch : between 연산

db.inventory.find(
	{ dim_cm: {$elemMatch: {$gt: 15, $lt: 20} } }
)
  • dim_cm array에 15이상, 20이하인 값을 포함하는 document 조회