MongoDB에서 특정 값의 최대 발생 횟수를 가진 배열 찾기
배열 필드 안에서 특정 값이 가장 많이 등장하는 문서를 찾고 싶다면 aggregate() 메서드를 활용하면 됩니다. 이 글에서는 예제 데이터를 준비하고, 집계 파이프라인을 단계별로 구성하여 원하는 문서를 조회하는 방법을 살펴봅니다.
1단계: 샘플 컬렉션 생성 및 문서 삽입
먼저 숫자 배열을 담은 문서 두 개를 컬렉션에 삽입합니다.
> db.countOccurrencesDemo.insertOne({"ListOfValues":[65,87,89,65,67,87,87,87]});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e06ef9325ddae1f53b621eb")
}
> db.countOccurrencesDemo.insertOne({"ListOfValues":[102,65,87,65,89,65,89,65,89,65]});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e06efaa25ddae1f53b621ec")
}2단계: find()로 전체 문서 확인하기
find() 메서드를 실행하면 컬렉션에 저장된 모든 문서를 확인할 수 있습니다.
> db.countOccurrencesDemo.find();
위 쿼리의 실행 결과는 다음과 같습니다.
{ "_id" : ObjectId("5e06ef9325ddae1f53b621eb"), "ListOfValues" : [ 65, 87, 89, 65, 67, 87, 87, 87 ] }
{ "_id" : ObjectId("5e06efaa25ddae1f53b621ec"), "ListOfValues" : [ 102, 65, 87, 65, 89, 65, 89, 65, 89, 65 ] }3단계: 집계 파이프라인으로 최대 발생 문서 조회하기
아래는 값 65가 가장 많이 등장한 문서를 찾는 쿼리입니다.
> db.countOccurrencesDemo.aggregate(
... [
... { "$project": {
... "ListOfValues": 1,
... "OccurencesValue": {
... "$size": {
... "$filter": {
... "input": "$ListOfValues",
... "as": "v",
... "cond": { "$eq": [ "$$v", 65] }
... }
... }
... }
... }},
... { "$group": {
... "_id": "$OccurencesValue",
... "MyValues": { "$push": "$$ROOT" }
... }},
... { "$sort": { "_id": -1 } },
... { "$limit": 1 }
... ]
... );파이프라인의 각 단계는 다음과 같은 역할을 합니다.
- $project: $filter로 ListOfValues 배열에서 65와 일치하는 요소만 걸러낸 뒤, $size로 그 개수를 세어 OccurencesValue 필드에 저장합니다.
- $group: 발생 횟수(OccurencesValue)를 기준으로 문서들을 그룹화하고, $push로 같은 그룹의 전체 문서를 MyValues 배열에 담습니다.
- $sort: 발생 횟수를 기준으로 내림차순 정렬합니다.
- $limit: 정렬 결과 중 가장 앞에 있는 문서 한 개만 반환합니다.
쿼리 실행 결과는 다음과 같습니다.
{ "_id" : 5, "MyValues" : [ { "_id" : ObjectId("5e06efaa25ddae1f53b621ec"), "ListOfValues" : [ 102, 65, 87, 65, 89, 65, 89, 65, 89, 65 ], "OccurencesValue" : 5 } ] }결과를 보면 두 번째 문서의 배열에는 값 65가 총 5번 포함되어 있어 첫 번째 문서(2회)보다 발생 빈도가 높습니다. 따라서 $sort와 $limit 조합에 의해 이 문서가 최종 결과로 반환됩니다.