The duplicates view groups photos that are alike, from loosely (they show the same thing) to strictly (the same shot, the same file). Pick how alike with a slider, review the groups, and share, delete or re-sync what you do not need.
- Tap the duplicates icon on the count line of the photos screen. The grid then shows the groups one after another, each under its own heading, with a slider above them.
- Refreshing (swipe down, the reload icon, a finished sync) keeps the duplicates view, on the same slider stop.
- You leave it with the duplicates icon again, a typed search, a filter, or an album.
The slider has 13 stops, 0 to 12, with the name of the kind of duplicate under it. It starts on stop 4. Its colour tells where you are: black at 0, green at 5, red at 10, and a neutral grey for 11 and 12.
Photos whose first 1 to 5 CLIP words are the same: the loosest kinds, for photos of the same thing.
Photos with the same camera details: the same shot, even when one of them was lightly edited.
The same camera details and the same first 1 to 5 CLIP words: the strictest kinds.
The file name only, without the folder, so a copy in another indexed folder is found.
The same size in bytes.
The duplicate keys are written by Opensolr when a photo is indexed (photos_ingest on api.opensolr.com), from CLIP's words and the photo's EXIF only — never from your tags or your own wording, so editing a photo does not move it between groups.
- Words: CLIP's first 1 to 5 words, lower-cased, de-duplicated and sorted, then hashed with md5.
- EXIF: date taken, camera make, camera model, lens, ISO, exposure, f-number, focal length, GPS position and altitude. File size, pixel size, orientation and modification time are left out on purpose, so a simple edit (a crop, a rotation, a filter) keeps the same key.
The keys live in the schema's *_hash dynamic field: indexed, not stored, with docValues. An index still on an older configuration has no keys yet; the app then says that finding duplicates needs the index reset for this version (see sync).
Each stop is one request to the phone's index: a /select with q=*:*, rows=0 and a JSON terms facet on that stop's field, keeping only values held by at least two photos, with the ids of the photos in each group. It is sent 300 ms after the slider settles, so dragging across the stops does not send a request for each one. Nothing is sent to Opensolr's AI services.
Select 1 of each duplicate, under the slider, ticks one photo of every group — the last of each — and leaves the first unticked, so every group keeps at least one photo. It only selects; review the ticks, change them if you like, then use the selection bar:
- Share the ticked photos.
- Delete them, after the app's own warning and, on Android 11 and newer, the system confirmation (see searching).
- Re-sync N to have them read again by Opensolr.