Which P1 Did the Lookup Mean?
Two sites use the same short asset ID. Build keys that preserve the full identity, and distinguish a missing entry from a stored zero.
12 sections · 4 questions · 1 coding challenge
The arrow keys move between sections too.
Small Operations Around Explicit Keys
BOTIE
That division gives the application responsibility for a naming convention. Our site and asset pair is an invented example. The key must carry enough identity before a key-value service can return the intended record.
Sources for this history
North and South Both Have a Pump Called P1
North reports no outstanding inspections for P1. South reports seven. Botie stores each answer under the key P1, and the second write replaces the first. The storage service did exactly what it was asked to do. Our key did not describe the thing we meant.
A key is the complete name used by a lookup. We need to decide which parts make that name unique, how those parts are encoded, and what an absent name means to the caller.
The local mapping uses a JSON-array key convention chosen for the exercise. Redis does not require that convention.
Step 1 of 2
Both writes targeted one name
The collision is in the application key.
| Actual asset | Incomplete key | Outstanding visits |
|---|---|---|
| north / P1 | P1 | 0 |
| south / P1 | P1 | 7 |
north / P1
- Incomplete key
- P1
- Outstanding visits
- 0
south / P1
- Incomplete key
- P1
- Outstanding visits
- 7
Step 2 of 2
A zero count is a useful answer
Separate presence from value.
- 1
Requested parts
north, P1 - 2
Encoded key
["north","P1"] - 3
Lookup result
found: true - 4
Stored value
0
A short asset name is only part of the identity
The key preserves site identity, while the found flag preserves zero.
Keep site identity in the lookup
Encode the requested site and asset before reading the store. Inspect the found flag independently of its value.
BOTIE
Status returned for the requested identity
0
Follow the operations
1. Stored status values
{ "[\"north\",\"P1\"]": 0, "[\"south\",\"P1\"]": 7 }2. Requested site and asset
- 0north
- 1P1
3. Encode all key parts
["north","P1"]
4. Look up one exact key
{ "found": true, "value": 0 }5. Missing status message
unavailable
6. Use a lookup or its fallback
0
7. Result
0
The browser runs an explicit model of the mechanism. It does not connect to MongoDB or Redis, simulate their query planners, or establish their concurrency guarantees.
1. Choose the scope of the identity
An asset ID can be unique inside a site while repeating elsewhere. The key therefore needs the site and asset. If customers can reuse site names, include the tenant too. A namespace for purpose or format version can keep different representations from colliding.
A well-formed key is still not an access-control decision. The server must verify that the caller may read the identified object. Letting a caller submit another tenant’s key does not establish that permission.
Identity describes the requested record. Authorisation decides whether this caller may access it.
2. Preserve boundaries when combining fields
Joining text can erase information. The pairs ["a:b", "c"] and ["a", "b:c"] produce the same colon-joined string. You can escape separators carefully, use length prefixes, or encode a structured sequence.
Our exercise encodes an ordered array of strings as compact JSON. Site always comes before asset. Every writer and reader must use the same encoding; a different spelling is a different key.
A key-value lookup performs an exact match.
3. Test membership before interpreting the value
A dictionary can contain a key whose value is zero, False, an empty string or None. Those values describe stored information. A missing key means there is no entry with that name.
Return a found flag separately when callers need to distinguish the states. Then a zero count reaches the screen unchanged, while a miss can trigger a fetch or an unavailable message.
bool(value) asks whether a value is truthy. It does not establish presence.
A stored zero is still a hit
Check the key before interpreting its count.
store = {"north:P1": 0}
for key in ["north:P1", "north:P9"]:
print(key, key in store, store.get(key))north:P1 True 0
north:P9 False NoneThe first count is known and zero. The second key is absent. A stored None would also need a separate presence check.
Check yourself
Questions on Parts 1 to 3
Question 1 of 2
What happened?
Use the information below.
The store contains north:P1 with value 0. GET succeeds and returns 0.4. Try the same operation at a Redis prompt
Redis string values are byte sequences. JSON text is one possible value format. SET replaces the value associated with a key; GET retrieves it. A missing GET has a null reply translated by the client into its own representation.
A real client can also report connection errors and timeouts. Those are different from a successful request reporting that no key exists. The Python worksheet keeps the naming mechanism visible without introducing a server.
The namespace in this command is an application choice.
Run in your own environment
SET and GET a site-specific count
These literal identifiers contain no separator characters. Use an unambiguous encoding for arbitrary identifiers.
Install redis-cli and start a disposable local Redis server. These commands do not run in the browser.
redis-cli SET 'asset:north:P1:open-count' '0'
redis-cli GET 'asset:north:P1:open-count'GET returns the stored string 0; presence does not depend on its numeric value.
SET and GET a site-specific count. Documentation checked .
5. Consider what another writer can do between requests
Two callers can read one counter, calculate replacements locally and write them back in either order. That read-modify-write sequence can lose an increment. Use the server’s appropriate atomic counter operation or a documented conditional-write protocol.
Also decide whether a replacement preserves expiry. Ordinary Redis SET clears an existing timeout unless an applicable expiry option is supplied. Naming the record correctly does not protect its update sequence or keep an old copy current.
The next lesson adds a deadline to the saved value.
Check yourself
Questions on Parts 1 to 5
Question 1 of 2
Which question does this expose?
Use the information below.
Two writers read 4, each adds one locally, and both write 5.Try it with Botie
Build with Botie
Write and run Python