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

MongoDB 객체 배열에서 서로 다른 객체의 속성을 비교하는 방법

개요

MongoDB에서 하나의 도큐먼트에 포함된 객체 배열 안에서 서로 다른 객체의 속성 값을 비교해야 하는 경우가 있습니다. 이럴 때는 $let 연산자와 $indexOfArray 연산자를 함께 사용하면 간단하게 해결할 수 있습니다.

이 글에서는 예제 컬렉션을 만들고, 배열 내 특정 객체들을 찾아 그 속성 값을 비교하는 쿼리를 단계별로 살펴보겠습니다.

1. 컬렉션 생성 및 문서 삽입

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

> db.demo366.insertOne(
...     {
...        "Name" : "Chris",
...        "details" : [
...        {
...           "Id" : "John1",
...           "value" : "test"
...        },
...        {
...           "Id" : "John2",
...           "value" : 18
...        },
...        {
...           "Id" : "John3",
...           "value" : 20
...        }
...    ]}
... );
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5e57ddd92ae06a1609a00ae7")
}

위 문서에는 details라는 객체 배열이 있으며, 각 객체는 Idvalue 필드를 가지고 있습니다.

2. 전체 문서 조회하기

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

> db.demo366.find();

실행 결과는 다음과 같습니다.

{
    "_id" : ObjectId("5e57ddd92ae06a1609a00ae7"), "Name" : "Chris", "details" : [
       { "Id" : "John1", "value" : "test" }, { "Id" : "John2", "value" : 18 },
       { "Id" : "John3", "value" : 20 }
    ]
}

3. 배열 내 객체 속성 비교 쿼리 작성하기

다음은 MongoDB 객체 배열에서 서로 다른 객체의 속성을 비교하는 쿼리입니다. 여기서는 Id가 "John2"인 객체의 value와 "John3"인 객체의 value를 비교합니다.

> db.demo366.find(
...    {"$expr":{
...       "$let":{
...          "vars":{
...             "john2":{"$arrayElemAt":["$details",{"$indexOfArray":["$details.Id","John2"]}]},
...             "john3":{"$arrayElemAt":["$details",{"$indexOfArray":["$details.Id","John3"]}]}
...    },
...    "in":{"$lt":["$$john2.value","$$john3.value"]}}
... }})

실행 결과는 다음과 같습니다.

{
    "_id" : ObjectId("5e57ddd92ae06a1609a00ae7"), "Name" : "Chris", "details" : [
       { "Id" : "John1", "value" : "test" }, { "Id" : "John2", "value" : 18 },
       { "Id" : "John3", "value" : 20 }
    ] 
}

"John2"의 value(18)가 "John3"의 value(20)보다 작기 때문에 조건을 만족하는 해당 문서가 결과로 반환되었습니다.

쿼리 동작 원리

  • $expr: find() 쿼리 안에서 집계(aggregation) 표현식을 사용할 수 있도록 해줍니다.
  • $let: vars 영역에서 변수를 정의하고, in 영역에서 해당 변수를 활용한 표현식을 실행합니다.
  • $indexOfArray: $details.Id 배열에서 "John2", "John3"에 해당하는 요소의 인덱스 위치를 찾습니다.
  • $arrayElemAt: 찾은 인덱스를 이용해 details 배열에서 해당 객체 전체를 추출합니다.
  • $lt: 두 변수($$john2.value, $$john3.value)의 값을 비교하여 앞의 값이 뒤의 값보다 작으면 true를 반환합니다.

마무리

이처럼 $let$indexOfArray를 조합하면 MongoDB 객체 배열 내부의 서로 다른 객체 속성을 자유롭게 비교할 수 있습니다. 이 기법은 배열 요소 간 조건 검색이 필요한 다양한 상황에서 유용하게 활용될 수 있습니다.