catalogue:read. This is not a second search: the same parser reads the
words and the same index ranks what is left, because a phone showing other
results than the website for the same words is a bug nobody can explain.
You do not need words. A request that only narrows —
filter[brand][]=Rolex
— is answered by the index too, with the same counts. Browsing by brand is the
same question as searching for one, and a filter panel is used far more often
than a search box.Drawing the panel before anybody has touched it
filter[q] is a search with no words: the whole catalogue, ranked, with
every facet and its counts. That is the call to make when the screen opens, before
somebody has typed or picked anything.
Leaving the parameter off altogether is a different request — the plain
cursor-paged list, which carries no facets because nothing was searched.
filter[seller] narrows any of this to one business — the shop page’s question.
It takes an id rather than a name, because two businesses share a name, and it
combines with words and facets like anything else: “everything this shop has under
€5,000” is one request.
That is the published catalogue. A seller’s own stock, drafts and sold listings
included, is /v1/sellers/{id}/watches and needs watches:read for that business.
A price range needs only the end you have: filter[price][min]=500000 on its own
means “from €5,000”, and filter[price][max] on its own means “up to”. Amounts are
cents, like every other amount here.
What the parser does with the words
Before anything is searched, the words are read for things that are not words:
Whatever is left over is what the index actually searches on. It reads Dutch,
English, German, French, Spanish, Italian, Portuguese, Finnish and Polish,
because sellers and buyers type in all of them.
What comes back
A count, not an estimate. The index is asked for a numbered page, which makes
it count the whole matching set rather than stopping as soon as it can answer.
The filter panel, keyed by the name you send back to filter on. A facet has a
name and a group to head it with, and either options — each a value, a
label, a count and whether it is active — or a range, for price.On the first page only. They describe the whole result set rather than the
slice, so they are the same on every page and repeating them was most of what
made one heavy. Keep the ones you were given.The hundred biggest, plus anything already active — except brand and
seller.name, which come whole so an A–Z list of them misses nothing. The index knows every
distinct value in the result set, which for watchModel is over a thousand and
for reference is roughly one per watch — a list nobody scrolls and a response
nobody wants. reference offers none for that reason, and so is left out
entirely rather than sent as a heading with nothing under it —
filter[reference] still works, because somebody looking for one types it. Any
facet that ends up with no options and no range is absent for the same reason, so
draw what you are given rather than expecting a fixed set.In the language you asked for. name, group and every option label
follow Accept-Language; value never does, because that is what you send back.Where in the list you are, in the same shape every other collection here uses —
so a client reads one thing whether somebody typed anything or not.
meta.total
and meta.pages beside it are the index’s own counts.Only present, and only
true, when the count stopped at the index’s own ceiling
(100,000). A search somebody actually runs never sees it; “everything we have”
might.A facet
Counts describe the narrowed set, so the panel stays honest as somebody ticks
things. A facet that nothing in the results has is left out rather than listed
with a zero.
Every facet you can filter on
Send them back exactly as they are keyed. All of them are arrays — several values of the same facet widen, different facets narrow.Sorting
The words themselves can sort: “goedkoopste rolex” is a price sort with a brand
filter, and a
sort you send wins over one the words implied.
year is the one sort that only works in a search — it is a specification rather than a
column, so anywhere else it is refused with 400 search_only_sort rather than ordering
“1998” against “2010” as text: on an inventory, and on a plain /v1/watches with neither
filter[q] nor a facet (send filter[q]= to sort the whole catalogue by year).
Paging
links.next is there until there is no next; meta.pages
says how many there are.
A seller’s own inventory pages by cursor instead —
page[after],
page[limit] — because walking a live inventory with an offset skips or repeats
rows when something is inserted halfway through.When there is nothing to show
An emptydata with meta.total: 0 means nothing matched. If the index is
unreachable the answer is 503 with code: search_unavailable — never an empty
page, because empty is an answer and it is not this one.