0Pricing
MongoDB Academy · 강의

$search 쿼리 작성하기: 텍스트, 구문, 와일드카드

학습자는 $search 집계 단계에서 텍스트, 구문, 와일드카드 연산자를 사용해 쿼리하고 검색 점수를 프로젝션합니다.

$search 쿼리 작성하기: 텍스트, 구문, 와일드카드은(는) CoddyKit의 무료 MongoDB Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 MongoDB Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. MongoDB Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.

The $search Aggregation Stage

Atlas Search queries are written using the $search aggregation stage—a special pipeline stage that routes the query to the Lucene engine rather than the MongoDB query planner. The $search stage must be the first stage in an aggregation pipeline. Inside it, you specify an operator (like text, phrase, or wildcard) that determines how the query string is matched against indexed documents.

The text Operator: Keyword Search

The text operator is the standard keyword search operator. It tokenizes the query string using the same analyzer used to build the index, then looks for documents containing those tokens. It supports multi-word queries where any word can match (OR semantics by default) and the path field specifies which indexed fields to search in—either a specific field name or all fields via { wildcard: '*' }.

db.articles.aggregate([
  {
    $search: {
      index: 'default',
      text: {
        query: 'mongodb aggregation pipeline',
        path: 'content'  // search in the 'content' field only
      }
    }
  },
  {
    $project: {
      title: 1,
      author: 1,
      score: { $meta: 'searchScore' }
    }
  },
  { $limit: 10 }
])

Searching Multiple Fields

The path field in a text operator can be a single field name, an array of field names, or the wildcard { wildcard: '*' } to search all indexed fields. When searching multiple fields, MongoDB combines results using the best score across fields. Searching fewer, more relevant fields typically produces better precision than searching all fields.

db.products.aggregate([
  {
    $search: {
      text: {
        query: 'noise cancelling headphones',
        path: ['name', 'description', 'tags'] // search in these three fields
      }
    }
  },
  { $limit: 20 }
])

// Or search all indexed fields:
db.products.aggregate([
  {
    $search: {
      text: {
        query: 'wireless bluetooth',
        path: { wildcard: '*' }
      }
    }
  }
])

The phrase Operator: Exact Phrase Matching

The phrase operator requires the query terms to appear in order and adjacent to each other in the document (like quoting a phrase in a search engine). This is more restrictive than text but much more precise—searching for 'machine learning' as a phrase will not match documents that only contain 'learning' and 'machine' in different sentences. Use slop to allow some words between terms.

db.articles.aggregate([
  {
    $search: {
      phrase: {
        query: 'machine learning model',
        path: 'content'  // all three words must appear in order
      }
    }
  },
  { $project: { title: 1, score: { $meta: 'searchScore' } } }
])

// With slop: allows up to 1 word between the terms
db.articles.aggregate([
  {
    $search: {
      phrase: {
        query: 'neural network',
        path: 'content',
        slop: 1  // allows 'neural deep network' to match
      }
    }
  }
])

The wildcard Operator: Pattern Matching

The wildcard operator matches documents where the field value matches a glob-style pattern using * (matches any sequence of characters) and ? (matches any single character). It searches against the indexed token values, so the behavior depends on the analyzer. For keyword-analyzed fields, it matches the entire stored string. Set allowAnalyzedField: true to use wildcard on analyzed fields (use with care—expensive for leading wildcards).

// Match SKUs starting with 'PROD-'
db.products.aggregate([
  {
    $search: {
      wildcard: {
        query: 'PROD-*',
        path: 'sku',  // keyword-analyzed field
        allowAnalyzedField: false
      }
    }
  }
])

// Match domains ending in '.org'
db.users.aggregate([
  {
    $search: {
      wildcard: {
        query: '*.org',
        path: 'email',
        allowAnalyzedField: true
      }
    }
  }
])

Projecting the Search Score

Atlas Search computes a relevance score for each result document indicating how well it matches the query. Access this score in a $project stage using { $meta: 'searchScore' }. By default, $search returns results in descending score order (most relevant first). Projecting the score also lets you filter on it—for example, discarding low-relevance results below a threshold.

db.articles.aggregate([
  {
    $search: {
      text: { query: 'cloud computing', path: 'body' }
    }
  },
  {
    $project: {
      title: 1,
      author: 1,
      publishedAt: 1,
      relevanceScore: { $meta: 'searchScore' }  // include the score
    }
  },
  // Only show results with score above 0.5
  { $match: { relevanceScore: { $gt: 0.5 } } },
  { $limit: 10 }
])

Combining $search With $match for Post-Filtering

You can follow $search with a $match stage to apply additional structured filters—for example, text search for 'headphones' and then filter to products with price under $100. However, use $searchMeta or the filter clause inside $search for pre-filtering on indexed fields, as post-match $match runs after all results are fetched and may be slower than filtering within the search stage.

db.products.aggregate([
  {
    $search: {
      compound: {
        must: [
          { text: { query: 'wireless headphones', path: 'name' } }
        ],
        filter: [
          // Pre-filter inside $search: much more efficient
          { range: { path: 'price', lte: 100 } },
          { equals: { path: 'inStock', value: true } }
        ]
      }
    }
  },
  { $project: { name: 1, price: 1, score: { $meta: 'searchScore' } } }
])

The range Operator for Numeric and Date Filtering

The range operator allows numeric or date range filtering inside the $search stage. This is more efficient than a post-search $match because Lucene applies the filter before fetching documents. Use gte, gt, lte, and lt bounds. The range operator works on fields indexed with type 'number' or 'date' in the Atlas Search index mapping.

db.jobs.aggregate([
  {
    $search: {
      compound: {
        must: [
          { text: { query: 'backend developer', path: 'title' } }
        ],
        filter: [
          {
            range: {
              path: 'postedAt',
              gte: new Date('2024-01-01'),
              lte: new Date('2024-12-31')
            }
          },
          {
            range: {
              path: 'salaryMin',
              gte: 80000
            }
          }
        ]
      }
    }
  }
])

The equals Operator for Exact Field Matching

The equals operator performs an exact equality match on a field—similar to MongoDB's standard equality filter but executed inside the Lucene engine. It works on boolean, number, date, objectId, and string fields. Using equals inside $search (rather than a post-search $match) allows Lucene to combine it with the text query efficiently using its bitset and skip-list optimizations.

db.listings.aggregate([
  {
    $search: {
      compound: {
        must: [
          { text: { query: 'beachfront villa', path: 'description' } }
        ],
        filter: [
          { equals: { path: 'available', value: true } },
          { equals: { path: 'bedrooms', value: 3 } }
        ]
      }
    }
  }
])

Performance: $search vs Native Text Index

Atlas Search generally outperforms MongoDB's native text indexes for complex queries because Lucene's inverted index is more sophisticated. However, for simple keyword lookups on small collections, the native $text operator may be sufficient. Key advantages of Atlas Search: better relevance scoring, per-field boosting, fuzzy matching, autocomplete, facets, and no one-text-index-per-collection limitation. Choose Atlas Search when you need any of these features.

Index Name Specification

When you have multiple Atlas Search indexes on a collection, specify the index field inside $search to select which index to use. If you omit it, Atlas Search uses the index named 'default'. Using named indexes allows different query types to use different index configurations—for example, a 'standard' index for keyword search and an 'autocomplete' index for type-ahead suggestions.

// Use the 'products_fulltext' search index
db.products.aggregate([
  {
    $search: {
      index: 'products_fulltext', // named index
      text: {
        query: 'standing desk ergonomic',
        path: ['title', 'description']
      }
    }
  }
]);

// Falls back to 'default' if index is not specified:
db.products.aggregate([
  {
    $search: {
      text: { query: 'monitor 4K', path: 'title' }
    }
  }
]);

Quick Check

Test your understanding of MongoDB & NoSQL Databases concepts from this lesson.

Lesson Recap

In this lesson you learned: $search must be the first pipeline stage and takes an operator like text, phrase, or wildcard, the text operator matches any token from the query while phrase requires tokens to appear in order, and use the compound operator with filter clauses to combine text search with structured filters efficiently inside the Lucene engine. Next up we explore autocomplete and fuzzy matching for typo-tolerant search.

자주 묻는 질문

“$search 쿼리 작성하기: 텍스트, 구문, 와일드카드” 강의는 무료인가요?

네 — “$search 쿼리 작성하기: 텍스트, 구문, 와일드카드” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 MongoDB Academy 강의 전체를 잠금 해제할 수 있습니다. MongoDB Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“$search 쿼리 작성하기: 텍스트, 구문, 와일드카드”에서 뭘 배우나요?

학습자는 $search 집계 단계에서 텍스트, 구문, 와일드카드 연산자를 사용해 쿼리하고 검색 점수를 프로젝션합니다. 브라우저에서 직접 실행하는 실습 코드로 MongoDB Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

MongoDB Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 MongoDB Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.

“$search 쿼리 작성하기: 텍스트, 구문, 와일드카드” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 MongoDB Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 MongoDB Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. Atlas Search 인덱스 만들기
  2. $search 쿼리 작성하기: 텍스트, 구문, 와일드카드
  3. 자동 완성 및 퍼지 일치
  4. 패싯 및 복합 쿼리
← MongoDB Academy(으)로 돌아가기