MongoDB 검색시 필요한 함수와 연산자 활용 예시

MongoDB Like 검색 및 관련 기능 활용 가이드

MongoDB에서 데이터를 검색할 때, 특정 패턴과 일치하는 문자열을 찾기 위해 $regex 연산자를 사용합니다. 즉 findaggregate$match 연산자에서 사용하는 것이다.

MongoDB에서 $regex 연산자를 사용하는 주된 이유는 그 유연성과 강력한 패턴 매칭 능력 때문인데 복잡한 문자열 패턴을 검색하거나 부분 문자열을 찾는 데 매우 효과적이며, 대소문자 구분 옵션 등 다양한 검색 조건을 설정할 수 있다. 다만, $regex는 인덱스 사용에 제한이 있어 성능 저하가 발생할 수 있으므로, 대규모 데이터셋에서는 주의가 필요하다. 따라서, $regex는 정교한 문자열 검색이 필요한 상황에서 강력한 도구이지만, 성능과 사용 목적을 고려하여 적절히 활용하기 위해 관련 내용을 정리해본다.

$regex 사용법

MongoDB에서 $regex 연산자를 사용하는 것은 정규식 처리의 안전성과 일관성을 높이는 방법이다. JSON 호환성 문제를 해결하고, 문자열 이스케이프 관련 오류를 방지하며, 정규식 옵션을 명확히 지정할 수 있게 해준다. 예를 들어, db.collection.find({ name: { $regex: "pattern", $options: "i" } })와 같이 사용하면, “pattern”이라는 정규식을 대소문자 구분 없이 검색할 수 있다. 이러한 방식은 MongoDB 쿼리에서 정규식을 더 안정적이고 효과적으로 활용할 수 있게 해준다.

// 예시: `typeArray.executeInfo.serviceType` 필드에 "api"를 포함하는 문서 검색

db.getCollection('intent_service_2').aggregate([
  {
    $match: {
      'typeArray.executeInfo.serviceType': {
        '$regex': 'api'
      }
    }
  }
]);

$regex 구문 형식

{ <field>: { $regex: /pattern/, $options: '<options>' } }
{ <field>: { $regex: 'pattern', $options: '<options>' } }
{ <field>: { $regex: /pattern/<options> } }

예:

{ $regex: 'ttt' }   // == /ttt/

$regex 활용 팁

  • 복잡한 패턴: 메타 문자 (예: . ^ $ * + ? { } [ ] \ | ( ))를 사용하여 정교한 패턴을 정의할 수 있다.
  • 옵션 사용: i (대소문자 무시), m (다중 라인), s (특수 문자 .이 모든 문자 일치) 등을 조합하여 검색 범위를 조절할 수 있다.
  • 한글 검색: 한글 정규 표현식을 사용할 경우 MongoDB 버전에 따라 처리 방식이 다를 수 있으므로 공식 문서를 참고.

MongoDB Unlike 검색

MongoDB에서는 특정 문자열을 포함하지 않는 문서를 검색할 수도 있습니다. 이를 위해 정규식을 활용하는데 내용은 다음과 같다.

패턴별 검색 예시

  1. 문자열을 포함하지 않는 문서 검색 db.collection.find({ name: { '$regex': '^((?!string).)*$', '$options': 'i' } });
  2. 대소문자 구분 없이 정확히 일치하는 문자열 검색 db.collection.find({ name: { '$regex': '^string$', '$options': 'i' } });
  3. 문자열로 시작하는 문서 검색 db.collection.find({ name: { '$regex': '^string', '$options': 'i' } });
  4. 문자열로 끝나는 문서 검색 db.collection.find({ name: { '$regex': 'string$', '$options': 'i' } });
  5. 문자열을 포함하는 문서 검색 db.collection.find({ name: { '$regex': 'string', '$options': 'i' } });

참고: StackOverflow MongoDB 검색 관련


MongoDB 필드명 변경

MongoDB에서 특정 필드명을 변경하려면 $rename 연산자를 사용한다. 아래 내용을 참고하시길 바란다.

$rename 사용법

// 조건에 따라 특정 필드명 변경

db.collection.update(
  { 조건 },
  {
    $rename: { "이전필드명": "변경할필드명" }
  },
  false,  // upsert 옵션
  true    // multiple 옵션
);

$rename 활용 팁

  • 배열 내 필드명 변경: 배열 내부의 필드명을 변경하려면 점 표기법을 사용하여 정확한 경로를 지정.

MongoDB 필드 삭제

필드 삭제를 위해 $unset 연산자를 사용할 수 있다. 이는 특정 조건에 따라 필드를 제거할 때 유용하다.

(다지우는게 아니다.)

$unset 사용법

  1. 모든 문서에서 특정 필드 삭제: db.collection.update( {}, { $unset: { "삭제할필드명의Path": 1 } }, false, true );
  2. 조건에 따라 특정 필드 삭제: db.collection.update( { '삭제할필드명의Path': { $exists: true } }, { $unset: { '삭제할필드명의Path': 1 } }, false, true );

배열 내 특정 필드 삭제

배열 내부의 필드를 삭제하려면 $exists와 positional operator $를 함께 사용할 수 있다.

db.collection.update(
  {
    'meta.asin': { $exists: true }
  },
  {
    $unset: { 'meta.$.asin': true }
  },
  false,
  true
);

주의: $unset은 해당 필드만 삭제하고 다른 필드는 유지한다. 즉 선택적으로 삭제하는 것이다.

나는 개인적으로 혹여 unset으로 다 지워지지 않을까 싶어 테스트도 먼저 해봤다.


MongoDB Find 검색에서 $group 연산자 대체 projection

find 명령어는 $group 연산자를 지원하지 않아 당황스러웠다. 다만 projection을 활용하여 원하는 데이터를 추출할 수 있어 find 명령어를 쓸 때는 projection을 주로 사용했다.

MongoDB의 find 명령어는 $group 연산자를 지원하지 않지않는다 다소 당황스러웠다… 다만 projection 기능을 활용하면 원하는 필드만 선택적으로 추출할 수 있다.

예시

db.getCollection('intent_service_sub').find(
  { intent: 'WishBook_Applying_Guide' },
  {
    _id: 0,
    intent: 1,
    'intentArrayList.intent': 1,
    'intentArrayList.sign': 1,
    'intentArrayList.serviceType': 1
  }
);

주의사항:

  • find는 문서 단위로 조회하므로, 문서 틀 안에서 필드와 값을 변경할 수 있다.
  • 새로운 자료구조 형태나 복잡한 집계 작업이 필요하다면 aggregate와 관련 연산자를 사용한다.

MongoDB 활용 사례

검색 기능 활용 시나리오

  • 로그 데이터 검색: 특정 패턴의 로그 메시지를 찾아 문제를 진단
  • 사용자 데이터 분석: 특정 조건을 만족하는 사용자를 찾아 분석

데이터 정제 및 변환

  • 불필요한 필드 삭제: $unset을 이용하여 정리
  • 필드명 변경: $rename을 통해 데이터 구조를 표준화

성능 최적화

  • Projection 활용: 불필요한 필드를 제외하여 네트워크 트래픽을 줄이고 성능을 향상
  • 인덱스 생성: 쿼리 성능 향상을 위해 적절한 인덱스를 설정

결론

MongoDB의 검색 기능은 유연하고 강력하여 다양한 데이터 분석 및 처리 작업에 활용될 수 있다.

$regex, $unset, $rename, find 등의 기본적인 연산자를 숙달하고, 필요에 따라 고급 기능을 활용하면 더욱 효과적인 데이터 관리가 가능하니 MongoDB를 DB로 활용할 생각이 있다면 반드시 해당 연산자는 파악하시길 바란다.

Leave a Comment

error: Content is protected !!