Computer >> 컴퓨터 >  >> 프로그래밍 >> MongoDB

MongoDB에서 배열 내 일치하는 객체의 개수를 기준으로 문서를 찾는 방법

MongoDB에서 배열(array) 내부에 특정 조건과 일치하는 객체가 몇 개 포함되어 있는지를 기준으로 문서를 조회해야 하는 경우가 있습니다. 이 글에서는 $where 연산자와 JavaScript 함수를 활용해 이러한 작업을 수행하는 방법을 예제와 함께 자세히 살펴보겠습니다.

1. 샘플 컬렉션 생성

먼저 insertOne() 메서드를 사용하여 문서가 담긴 컬렉션을 생성합니다.

> db.demo694.insertOne(
...    {
...       "details" :
...       [
...          {
...             "Name" : "Chris",
...             Age:21
...          },
...          {
...             "Name" : "David",
...             Age:22
...          }
...       ]
...    }
... );
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5ea59279ece4e5779399c07f")
}
> db.demo694.insertOne(
...    {
...       "details" :
...       [
...          {
...             "Name" : "Bob",
...             Age:21
...          },
...          {
...             "Name" : "Mike",
...             Age:23
...          }
...       ]
...    }
... );
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5ea5927aece4e5779399c080")
}
> db.demo694.insertOne(
...    {
...       "details" :
...       [
...          {
...             "Name" : "Chris",
...             Age:21
...          },
...          {
...             "Name" : "Carol",
...             Age:22
...          }
...       ]
...    }
... );
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5ea5927aece4e5779399c081")
}

2. 전체 문서 확인하기

find() 메서드를 사용하면 컬렉션에 저장된 모든 문서를 확인할 수 있습니다.

> db.demo694.find();

위 명령을 실행하면 다음과 같은 결과가 출력됩니다.

{ "_id" : ObjectId("5ea59279ece4e5779399c07f"), "details" : [ { "Name" : "Chris", "Age" : 21 }, { "Name" : "David", "Age" : 22 } ] }
{ "_id" : ObjectId("5ea5927aece4e5779399c080"), "details" : [ { "Name" : "Bob", "Age" : 21 }, { "Name" : "Mike", "Age" : 23 } ] }
{ "_id" : ObjectId("5ea5927aece4e5779399c081"), "details" : [ { "Name" : "Chris", "Age" : 21 }, { "Name" : "Carol", "Age" : 22 } ] }

3. 배열 내 일치 객체의 개수를 기준으로 문서 조회하기

다음은 배열 내에서 조건과 일치하는 객체의 개수를 기준으로 MongoDB에서 문서를 찾는 쿼리입니다. 여기서는 $where 연산자와 함께 JavaScript 함수를 정의하여, Name이 "Chris"이고 Age가 21인 객체가 details 배열 안에 최소 1개 이상 포함된 문서만 필터링합니다.

> nameChrisAge21= function () {
...    var inc = 0;
...    this.details.forEach(function (d) {
...       if (d.Name == "Chris" && d.Age == 21) {
...          inc= inc + 1;
...       }
...    });
...    if (inc >= 1) {
...       return true;
...    }
... }
function () {
   var inc = 0;
   this.details.forEach(function (d) {
      if (d.Name == "Chris" && d.Age == 21) {
         inc= inc + 1;
      }
   });
   if (inc >= 1) {
      return true;
   }
}
> db.demo694.find({$where:nameChrisAge21});

위 쿼리를 실행하면 다음과 같은 결과가 출력됩니다.

{ "_id" : ObjectId("5ea59279ece4e5779399c07f"), "details" : [ { "Name" : "Chris", "Age" : 21 }, { "Name" : "David", "Age" : 22 } ] }
{ "_id" : ObjectId("5ea5927aece4e5779399c081"), "details" : [ { "Name" : "Chris", "Age" : 21 }, { "Name" : "Carol", "Age" : 22 } ] }

결과를 보면 첫 번째 문서와 세 번째 문서만 반환된 것을 확인할 수 있습니다. 두 문서 모두 details 배열에 "Chris"(나이 21) 객체가 포함되어 있어 조건을 충족하기 때문입니다.

참고 사항

$where 연산자는 컬렉션의 각 문서에 대해 JavaScript 코드를 실행하는 방식으로 동작합니다. 이로 인해 실행 속도가 느려질 수 있고 인덱스를 활용할 수 없다는 단점이 있습니다. 따라서 대량의 데이터를 다루는 운영 환경에서는 집계 파이프라인(aggregation pipeline)의 $match 단계와 $expr, $filter, $size 연산자를 조합해 배열 요소 개수를 계산하는 방식을 사용하는 것이 더 효율적입니다. 소규모 데이터나 복잡한 조건이 필요한 임시 조회에는 $where 방식이 유용하게 활용될 수 있습니다.