본문 바로가기
데이터베이스/MongoDB

[MongoDB] $elemMatch (query)

by minhyeok.lee 2023. 3. 10.
반응형

[MongoDB] 몽고 DB에서 배열 요소에 대한 쿼리, $elemMatch (query)

 

$elemMatch 연산자는 지정된 모든 쿼리 기준과 일치하는 요소가 하나 이상 있는 배열 필드가 포함된 문서와 일치한다.

{ <field>: { $elemMatch: { <query1>, <query2>, ... } } }

 - 단일 <query> 조건만 지정하는 경우 $elemMatch 표현식 내부에 $not 또는 $ne 연산자를 사용하지 않는다.

 - $elemMatch , $elemMatch 생략할 수 있다.

 - $elemMatch안에서 $where 식을 지정할 수 없다.

 - $elemMatch안에서 $text 쿼리 식을 지정할 수 없다.

 

 

요소 일치

* MongoDB Shell에서 진행

아래와 같은 문서 내용을 삽입해준다.

db.scores.insertMany([
	{ _id: 1, results: [ 13, 82, 99 ] }
	{ _id: 2, results: [ 44, 77, 89 ] }
]);

 

다음 쿼리는 결과 배열에 80보다 크거나 같고 85보다 작은 요소가 하나 이상 포함된 문서에만 일치한다.

db.scores.find(
   { results: { $elemMatch: { $gte: 80, $lt: 85 } } }
)

 

쿼리는 _id:1의 result 배열의 요소 82가 80보다 크거나 같고 85보다 작기 때문에 _id:1의 문서를 반환한다.

[
	{ "_id" : 1, "results" : [ 13, 82, 99 ] }
]

 

 

포함된 문서 배열

* MongoDB Shell에서 진행

아래와 같은 문서 내용을 삽입해준다.

db.survey.insertMany( [
   { "_id": 1, "results": [ { "goods": "abc", "score": 10 },
                            { "goods": "xyz", "score": 5 } ] },
   { "_id": 2, "results": [ { "goods": "abc", "score": 8 },
                            { "goods": "xyz", "score": 7 } ] },
   { "_id": 3, "results": [ { "goods": "abc", "score": 7 },
                            { "goods": "xyz", "score": 8 } ] },
   { "_id": 4, "results": [ { "goods": "abc", "score": 7 },
                            { "goods": "def", "score": 8 } ] }
] )

 

 

다음 쿼리는 결과 배열에 goods가 모두 "xyz"이고 점수가 8보다 크거나 같은 요소가 하나 이상 포함된 문서와 일치한다.

db.survey.find(
   { results: { $elemMatch: { goods: "xyz", score: { $gte: 8 } } } }
)

 

쿼리는 다음 문서와 일치한다.

[
    { "_id" : 3, "results" : [ { "goods" : "abc", "score" : 7 },
                           { "goods" : "xyz", "score" : 8 } ] }
]

 

 

단일 쿼리 조건

1) 단일 쿼리 술어를 지정하는 경우 $elemMatch 표현식 내부에 $not 또는 $ne 연산자를 사용하지 않는다.

2) $elemMatch , $elemMatch 생략할 수 있다.

 

$elemMatch를 사용한 쿼리 예시)

db.survey.find(
   { results: { $elemMatch: { goods: "xyz" } } }
)

 

$elemMatch를 사용하지 않은 쿼리 예시)

db.survey.find(
   { "results.goods": "xyz" }
)

 

$elemMatch를 사용한 출력값과 $elemMatch를 사용하지 않은 출력값은 동일하다.

[
   { "_id": 1, "results": [ { "goods": "abc", "score": 10 },
                            { "goods": "xyz", "score": 5 } ] },
   { "_id": 2, "results": [ { "goods": "abc", "score": 8 },
                            { "goods": "xyz", "score": 7 } ] },
   { "_id": 3, "results": [ { "goods": "abc", "score": 7 },
                            { "goods": "xyz", "score": 8 } ] }
]

 

 

$elemMatch에 $not, $ne가 포함

* $elemMatch 식에 $not 또는 $ne 연산자가 포함된 $elemMatch 표현식은 반환된 문서를 변경하고 서로 다른 문서를 반환한다.

 

$elemMatch를 사용한 쿼리 예시)

db.survey.find(
   { "results": { $elemMatch: { goods: { $ne: "xyz" } } } }
)

 

$elemMatch를 사용한 예시로 위 쿼리는 다음 문서를 반환한다.

[
    { "_id" : 1, "results" : [ { "goods" : "abc", "score" : 10 },
                           { "goods" : "xyz", "score" : 5 } ] }
    { "_id" : 2, "results" : [ { "goods" : "abc", "score" : 8 },
                           { "goods" : "xyz", "score" : 7 } ] }
    { "_id" : 3, "results" : [ { "goods" : "abc", "score" : 7 },
                           { "goods" : "xyz", "score" : 8 } ] }
    { "_id" : 4, "results" : [ { "goods" : "abc", "score" : 7 },
                           { "goods" : "def", "score" : 8 } ] }
]

결과 배열의 하나의 goods라도 "xyz"가 아닌 문서를 반환한다.

 

$elemMatch를 사용하지 않은 쿼리 예시)

db.survey.find(
   { "results.goods": { $ne: "xyz" } }
)

 

$elemMatch를 사용하지 않은 예시로 위 쿼리는 다음 문서를 반환한다.

[
    { "_id" : 4, "results" : [ { "goods" : "abc", "score" : 7 },
                           { "goods" : "def", "score" : 8 } ] }
]

결과 배열의 모든 goods가 "xyz"가 아닌 문서를 반환한다.

 

반응형

댓글