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

MongoDB에서 순위/검색 횟수를 계산하는 쿼리 작성 방법

MongoDB에서 검색어와 문서의 일치 정도를 기준으로 순위(ranking) 또는 검색 횟수(search count)를 계산하려면 aggregate() 메서드를 활용하면 됩니다. 이 글에서는 배열 필드와 검색어 목록의 교집합 비율을 구해 순위 점수를 산출하고, 내림차순으로 정렬하는 방법을 단계별로 살펴봅니다.

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

먼저 데모용 컬렉션을 만들고 문서를 삽입합니다. 각 문서는 이름(Name)과 과목 목록(Subjects) 배열을 가지고 있습니다.

> db.demo120.insertOne(
...     {
...        'Name': 'Chris',
...        'Subjects': [ 'MySQL', 'MongoDB', 'Java', 'Python' ]
...    }
... );
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5e2f11aed8f64a552dae6365")
}
> db.demo120.insertOne(
...     {
...        'Name': 'Bob',
...        'Subjects': [ 'C', 'MongoDB' ]
...    }
... );
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5e2f11afd8f64a552dae6366")
}

2. find()로 전체 문서 확인하기

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

> db.demo120.find();

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

{ "_id" : ObjectId("5e2f11aed8f64a552dae6365"), "Name" : "Chris", "Subjects" : [ "MySQL", "MongoDB", "Java", "Python" ] }
{ "_id" : ObjectId("5e2f11afd8f64a552dae6366"), "Name" : "Bob", "Subjects" : [ "C", "MongoDB" ] }

3. 순위/검색 횟수 계산 쿼리

이제 핵심인 집계(aggregation) 쿼리입니다. 검색어 배열 s를 정의한 뒤, 다음 파이프라인 단계를 거칩니다.

  • $match: Subjects 필드가 검색어 중 하나라도 포함하는 문서만 필터링합니다.
  • $addFields: RankSearch라는 새 필드를 추가합니다. 이 값은 $setIntersection으로 구한 두 배열의 교집합 크기를 원래 Subjects 배열의 크기로 나눈 값입니다.
  • $sort: RankSearch 값을 내림차순(-1)으로 정렬해 일치도가 높은 문서를 상위에 배치합니다.
> var s = ['MySQL', 'Java', 'MongoDB'];
> db.demo120.aggregate([
...     { "$match": { "Subjects": { "$in": s } } },
...     {
...         "$addFields": {
...             "RankSearch": {
...                 "$divide": [
...                     { "$size": { "$setIntersection": ["$Subjects",s] } },
...                     { "$size": "$Subjects" }
...                 ]
...             }
...         }
...     },
...     { "$sort": { "RankSearch": -1 } }
... ])

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

{ "_id" : ObjectId("5e2f11aed8f64a552dae6365"), "Name" : "Chris", "Subjects" : [ "MySQL", "MongoDB", "Java", "Python" ], "RankSearch" : 0.75 }
{ "_id" : ObjectId("5e2f11afd8f64a552dae6366"), "Name" : "Bob", "Subjects" : [ "C", "MongoDB" ], "RankSearch" : 0.5 }

결과 해석

Chris의 경우 과목 4개 중 MySQL, MongoDB, Java 3개가 검색어와 일치하므로 순위 점수는 3/4 = 0.75입니다. Bob은 과목 2개 중 MongoDB 1개만 일치하므로 1/2 = 0.5입니다. 따라서 Chris가 더 높은 순위로 정렬됩니다.

이처럼 $setIntersection과 $size, $divide 연산자를 조합하면 별도의 검색 엔진 없이도 MongoDB 자체적으로 간단한 관련도(relevance) 기반 순위 점수를 계산할 수 있습니다.