Start learning free

LESSON 58 OF 66 · NOSQL: MONGODB

An Index on Two Fields

Practice

The shop's most common search picks one category and lists it from the dearest product to the cheapest. An index on category alone finds that category fast, but the server still has to sort it by price every time. A compound index holds two fields: it is sorted by the first, and inside each value of the first, by the second. You give create_index a list of (field, direction) pairs, 1 going up and -1 going down, like SQL's CREATE INDEX … ON products (category, price DESC).

An example on the customers: city going up, and inside each city the newest joined date first.

db.customers.create_index([("city", 1), ("joined", -1)])

MongoDB names it city_1_joined_-1, after its fields and directions. index_information() gives back a dict with one entry per index: its name, and a dict about it whose "key" lists the fields with their directions. The index also serves searches on the city alone, but not on joined alone, the way a phone book sorted by last name finds every Smith fast but not every Anna. So an older index on the first field alone only adds work to every insert and update: drop_index removes it by name.

Unique on two fields: with unique=True, a compound index refuses a document whose pair of values is already there, like SQL's UNIQUE (customer_id, product), and raises DuplicateKeyError; each field alone can still repeat. The hidden setup adds four reviews (customer 1 reviewed the Mug and the Pen, customer 3 the Plant, customer 4 the Teapot) and makes the category_1 index again. This lesson runs on an in-memory MongoDB that takes the same calls, and the same code runs on a real server. The stand-in keeps and enforces indexes but has no query plan: on a real server, .explain() on a find shows the index in use.

Your lines, the kitchen search already in the editor and the hidden check together print:

_id_ [('_id', 1)]
category_1 [('category', 1)]
category_1_price_-1 [('category', 1), ('price', -1)]
Teapot 22
Mug 12
Product indexes: ['_id_', 'category_1_price_-1']
Customer 1 reviews the Mug again: refused
Customer 1 reviews the Notebook: saved
Customer 3 reviews the Mug: saved
Reviews: 6

Your task: below db, create one index on the products' category going up and price going down, loop over index_information() printing each name and its "key", then drop "category_1". Below the kitchen search, create a unique index on the reviews' customer_id and product together.


Assignment
Follow the Coding Tutorial to build the compound index, list and tidy the products' indexes, and make each customer's review of a product unique.


Hint
The order of the pairs matters: category first, then price with -1. drop_index takes the index's name as a string. The reviews index is a list of two pairs, plus unique=True.


STEP 1 OF 5
    Ctrl + Enter to check