Search goes straight from the app to the phone's index, in a single request. What you type can match the words a photo was read into, and on plans with vector search, what your words mean.
Figure 1 — a typed search, an optional query vector, one POST to the index, results that open in the gallery.
With nothing typed, the grid lists every photo in the index, newest first (q=*:*, sorted by the date taken). This is what you see when the app opens.
What you type is trimmed to 300 characters and sent only as the bound parameter uq. The query that uses it is fixed in the app:
meaning holds the words CLIP read the photo into and weighs the most. text also collects the file name, the folder, the camera, and the place the photo was taken in (city, region, country), so typing screenshots, pixel or Bucharest finds what you would expect. Words are matched with stemming and accent folding, so dogs finds dog and bucuresti finds Bucureşti.
From the second character on, a short list appears under the search box: the words your own photos were read into, the camera makes and models, and the places they were taken in, all of them matched anywhere in the term (cat offers tabby cat). Tap one and it searches. The list comes from the index's /suggest handler, a Solr suggester built from the suggest field and rebuilt at every commit, so a photo that was just indexed is offered right away.
Every typed search is also spellchecked against the same words, camera names and places (the spell field, checked by Solr's DirectSolrSpellChecker). When a correction exists, Did you mean briefcase? appears above the results, one tap away. Only the words your photos actually carry can be suggested: the dictionary is your index, nothing else.
On a plan with vector search, the app first asks Opensolr's embed endpoint to turn your words into a query vector, then adds it next to the words:
A photo can be found by the words, by the meaning, or by both, and the ones that match both rank highest. The line above the results says matched by meaning and words when the vector was used.
Without vector search on the plan, when this month's AI requests are used up, or when the vector service does not answer, the same request runs with words only, and a note above the results says why.
- Your text only ever travels in
uq, read by the query throughv=$uq. It is never pasted into the query syntax, so characters such as braces, colons or quotes are just characters. - Every filter value travels the same way, through the
termparser with a bound value (see filters). - Page size is clamped and the start offset cannot be negative.
- The request is a POST: a query vector is too long for a URL, and a request body keeps what you searched for out of server access logs.
Results come 60 at a time and more load as you scroll. The thumbnails are drawn from the photos on your phone; nothing is downloaded to show the grid. Tapping and holding a photo is described in filters & photo details.
- Enter on the keyboard runs the search.
- Reload: swipe down on the grid, or tap the reload icon next to the photo count, to read the results again from the index — for photos a sync added in the meantime. Coming back to the photos from the Sync or Account screen reloads them as well.
- The map icon at the top opens the map with the photos of the current search that carry a place.