MongoDB에서 배열 내 특정 요소의 인덱스(위치)를 확인해야 할 때가 있습니다. 이럴 때 유용하게 사용할 수 있는 것이 바로 $indexOfArray 집계 연산자입니다. 이 연산자는 지정한 값이 배열 내 몇 번째 위치에 있는지 반환하며, 해당 값이 존재하지 않을 경우 -1을 반환합니다.
1. 샘플 컬렉션 생성하기
먼저 실습용 컬렉션을 만들고 문서를 삽입해 보겠습니다.
> db.demo65.insertOne({"ListOfValues":[10,20,30]});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e28990ecfb11e5c34d89938")
}
> db.demo65.insertOne({"ListOfValues":[50,60,70,100]});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e28991ecfb11e5c34d89939")
}
> db.demo65.insertOne({"ListOfValues":[30,40,89,91,98]});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e28992bcfb11e5c34d8993a")
}2. 저장된 문서 조회하기
find() 메서드를 사용하여 컬렉션에 저장된 모든 문서를 확인합니다.
> db.demo65.find();
위 쿼리를 실행하면 다음과 같은 결과가 출력됩니다.
{ "_id" : ObjectId("5e28990ecfb11e5c34d89938"), "ListOfValues" : [ 10, 20, 30 ] }
{ "_id" : ObjectId("5e28991ecfb11e5c34d89939"), "ListOfValues" : [ 50, 60, 70, 100 ] }
{ "_id" : ObjectId("5e28992bcfb11e5c34d8993a"), "ListOfValues" : [ 30, 40, 89, 91, 98 ] }3. $indexOfArray로 배열 요소의 인덱스 찾기
이제 aggregate() 파이프라인과 함께 $project 단계를 사용하여, 각 문서의 ListOfValues 배열에서 값 30이 위치한 인덱스를 찾아보겠습니다.
> db.demo65.aggregate(
... [
... {
... $project:
... {
... IndexOfAnArrayElement: { $indexOfArray: [ "$ListOfValues", 30] },
... }
... }
... ]
... );4. 실행 결과 확인하기
쿼리 실행 결과는 다음과 같습니다.
{ "_id" : ObjectId("5e28990ecfb11e5c34d89938"), "IndexOfAnArrayElement" : 2 }
{ "_id" : ObjectId("5e28991ecfb11e5c34d89939"), "IndexOfAnArrayElement" : -1 }
{ "_id" : ObjectId("5e28992bcfb11e5c34d8993a"), "IndexOfAnArrayElement" : 0 }결과 해석
- 첫 번째 문서: 배열 [10, 20, 30]에서 30은 세 번째 요소이므로 인덱스 2가 반환됩니다. (인덱스는 0부터 시작합니다.)
- 두 번째 문서: 배열 [50, 60, 70, 100]에는 30이 존재하지 않으므로 -1이 반환됩니다.
- 세 번째 문서: 배열 [30, 40, 89, 91, 98]에서 30은 첫 번째 요소이므로 인덱스 0이 반환됩니다.
$indexOfArray는 MongoDB 3.4 버전부터 도입된 연산자로, 배열 검색 로직을 애플리케이션 코드 없이 데이터베이스 레벨에서 처리할 수 있게 해줍니다. 참고로 이 연산자는 선택적으로 시작 위치와 종료 위치를 추가 인자로 지정하여 특정 범위 내에서만 검색하는 것도 가능합니다.