liveBook · Manning

Faceted search

As explained in MongoDB 8.0 in Action, Third Edition

Faceted search presents categorized result groups with counts so users can filter and refine a result set.

Faceted search divides matching records into categories and reports how many fall in each one. A search interface can use those counts to help people choose filters—for example, narrowing business-inspection results by outcome, year, or sector. section 11.5.1

To produce facets with MongoDB Atlas Search:

  • Run a $search stage against an Atlas Search index to select the matching documents. A fuzzy text query can tolerate minor spelling errors in the search terms. section 11.5.1
  • Follow it with an aggregation $facet stage. Give each branch a distinct job, such as counting matches by inspection result, extracting and counting inspection years, or counting sectors. section 11.5.1
  • Present each branch’s categories and counts as ways to understand or refine the matches. A $limit after $facet appears in the inspection example only for illustration; it is not typically needed there. section 11.5.1

Business-inspection results

A fuzzy search for “HOT DOG” in business names produces counts by inspection status, year, and sector. The year groups contain 74 matches from 2015 and 8 from 2016. A separate search for “BUILDING” counts 29 total matches and also groups them by status and ZIP code. These counts describe the matched set; the examples do not show a user selecting a facet to run a narrower query. section 11.5.1

db.inspections.aggregate([
  {
    $search: {
      index: "MongoDB-in-Action",
      text: {
        query: "HOT DOG",
        path: "business_name",
        fuzzy: {
          maxEdits: 1, // Allows for one typo
          prefixLength: 3 // The first 3 letters must be exactly the same
        }
      }
    }
  },
  {
    $facet: {
      "ResultsByStatus": [
        { $group: { _id: "$result", count: { $sum: 1 } } }
      ],
      "ResultsByYear": [
        {
          $group: {
            _id: { $year: { $dateFromString: { dateString: "$date" } } },
            count: { $sum: 1 }
          }
        }
      ],
      "SectorSummary": [
        { $sortByCount: "$sector" }
      ]
    }
  },
  { $limit: 1 } // This is only for illustration;
                ➥ // typically, limit wouldn't be
                ➥ // used after a facet.
])

Inspect the complete “HOT DOG” pipeline to see $search feed three named $facet branches. section 11.5.1

[
  {
    ResultsByStatus: [
      { _id: 'No Violation Issued', count: 30 },
      { _id: 'No Evidence of Activity', count: 5 },
      { _id: 'Unable to Locate', count: 3 },
      { _id: 'Out of Business', count: 5 },
      { _id: 'Posting Order Served', count: 1 },
      { _id: 'Violation Issued', count: 19 },
      { _id: 'Pass', count: 19 }
    ],
    ResultsByYear: [ { _id: 2015, count: 74 }, { _id: 2016, count: 8 } ],
    SectorSummary: [
      { _id: 'Cigarette Retail Dealer - 127', count: 32 },
      { _id: 'Grocery-Retail - 808', count: 20 },
      { _id: 'Misc Non-Food Retail - 817', count: 12 },
      { _id: 'Mobile Food Vendor - 881', count: 6 },
      { _id: 'Wearing Apparel - 450', count: 5 },
      { _id: 'Salons And Barbershop - 841', count: 3 },
      { _id: 'Tow Truck Company - 124', count: 2 },
      { _id: 'Restaurant - 818', count: 1 },
      { _id: 'Tax Preparers - 891', count: 1 }
    ]
  }
]

Compare the pipeline with its grouped status, year, and sector counts. section 11.5.1

How MongoDB 8.0 in Action, Third Edition covers it

How deep it goes
Works through fuzzy matching and counts by status, year, and sector, but does not show interface wiring or a selected-facet query.
Examples
Uses business-inspection searches for “HOT DOG” and “BUILDING,” with counts by outcome, year, sector, or ZIP code.
What it assumes
Assumes an Atlas Search index for the queried collection and familiarity with aggregation stages; demonstrates the stages rather than index setup.
What you can do after
Build it from scratch with Atlas Search $search and aggregation $facet to count matching records by several fields.
How it connects
Connects full-text search, fuzzy search, Atlas Search, aggregation pipelines, and range search.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of MongoDB 8.0 in Action, Third Edition. The section links point to the parts of the book it draws on.