The app uploads the files in solr/conf of its repository to the phone's index: schema.xml, solrconfig.xml, stopwords.txt, synonyms.txt and protwords.txt. The build zips that folder into the APK, so the app always uploads exactly what is in the repository.
idmd5 of the absolute path, lower-case hex
pathAbsolute path on the phone
folderMediaStore folder, e.g. DCIM/Camera/
file_nameFile name
media_idMediaStore id, used to open the photo
mime, size_bytesType and file size
width, heightPixels as displayed, EXIF rotation applied
orientationlandscape, portrait or square
taken_atEXIF date taken with its offset when present, otherwise MediaStore's date
year, monthFrom taken_at, in the phone's time zone
modified_atFile modification time
camera_make, camera_model, lensFrom EXIF
iso, exposure, f_number, focal_length, flashFrom EXIF; exposure as 1/250
has_location, location, altitudeGPS as lat,lon when usable; location is a spatial field, so it answers radius searches
city, region, province, community, country, country_codeThe nearest named place to the position, in words, from Opensolr's nearby_places
meaningThe CLIP words joined with commas
labelsThe CLIP words one by one
embeddings1024 dimensions, cosine; the vector of meaning
clip_model, embed_modelWhat produced the words and the vector
indexed_atWhen the document was written
Copy fields feed the search fields: text gathers meaning, file name, folder, camera, city, region and country; file_name_text, folder_text, camera_text and place_text hold each of those on its own. Two more copy fields serve typing: suggest (labels, camera make and model, city, region, province, country) is what autocomplete offers, and spell (the same plus the file name) is what Did you mean checks against. Dynamic fields (*_s, *_ss, *_i, *_l, *_f, *_b, *_dt, *_t) are there for anyone extending the app.
All search fields use one analyzer: standard tokenizer, stop words, lower case, accent folding, English possessives, protected words, and KStem, so dogs matches dog. At query time a short synonym list adds photo, picture, image, pic, sea, ocean and a few more. The spell field and the suggester use a second, unstemmed analyzer (text_spell: tokenizer, lower case, accent folding), so corrections and completions come back as real words.
The vectors come from Opensolr's embedding service, the same one every Opensolr vector index uses. The dimension is fixed by that service.
Deliberately small: Lucene match version 9.0, the classic schema factory (so schema.xml is the schema), a soft commit every 10 seconds and a hard commit every 60, a /select handler answering JSON with 60 rows by default and carrying the spellcheck component (off unless the app asks for it), a /suggest handler with one suggester (AnalyzingInfixLookupFactory over the suggest field, rebuilt at every commit), and /update. Remote streaming and stream bodies are off. There are no <lib> directives, no script processors and no response writers that run templates.
The app tells an index on an older configuration apart by the newest field of the schema, uploads the current files, and writes every photo again from the phone's cache. Nothing is asked of you and nothing costs AI requests. See the phone's index.