Search for single KW (exclusively)

Hy

I use the “kw:” search term a lot since all my pictures are tagged that way.
However one question:
Is it possible to search a picture that has eactly just this keyword and no other keyowrds.
Example:
Picture 1 has keywords: Andi, Michael
Picture 2 has keywords: Andi

Now if I search with kw:Andi it will show both pictures. So how can I search for picture 2 where only exactly Andi and nothing else is present?

Welcome to PhotoStructure, @GekoCH!

There isn’t a way that I can think of to support implicit exclusivity with the current code.

Explicit exclusions are supported, though:

Andi -Michael

hmm ok thats probably the reason why I wrote my own program to get exactly this feature.
I use this a lot to get for example only pictures from one family member alone on the picture and not with other persons.

I have made this possible by use a little toggle switch to only search exactly for this who tag and no other who tag is allowed to be present

Interesting.

If we wanted to add this as a new feature, have you seen this in other search engines before? What would you expect the syntax to look like?

or how do other people solve this problem when you like photos with just one particular person on it?
Or is there no demand for such a feature?

I suspect there may be, as soon as face tagging is available!

I can’t say I have ever seen such a feature in any of the other tools I’ve used, but this would have been handy a couple times in the last year or so…

I’ve been trying to come up with an example syntax, but not sure I’ve found anything I like yet.

Considered quotes - “exclusive term”, but that overlaps with searches that include spaces.

Maybe just an -exclusive:’term’ tag

nice to see others would like to have also such a feature.
the important part of course is that the “exclusive” does only act on the “who” tag an not the other tags as well.
So that we can search a single person and still use the “where” or “date” tag to further narrow the search down

Agreed, although whatever syntax should be capable of being applied to other items I would think…. At least with general tags in addition to people tags

That’s a good clarification.

I’ve thought a bit about how to implement this, and unless there’s some clever way I can annotate indexed records when they’re rebuilt, this is going to be a really expensive query.

SQL and full-text search (FTS) indexes don’t really have an idea of an “exclusive” operator: you have to negate an inclusion clause, which means “ONLY who:Andi” is implemented by who:Andi AND -who:Michael AND -who:Alice AND ...(every other person name in your library) (or if you think in SQL, WHERE NOT IN (...every person name in your library...) This isn’t tenable.

So…

There could be a synthetic value added to the search index which has a “sibling tag count.” Behind the scenes, the FTS index already has a “path” column for tag names, so we’d add something like “sibling-count” column. This would expand the index size per asset, though.

We’d then need to add a namespace or operator to act on this new column.

I’ll keep thinking about it. Alternative solutions are welcome.

(Note that I have a ton of other features that I need to ship before this: I try to work in most-voted order).

I had the same problem with SQL and I did first search for the name in the search form so for example “andi” and filled an array with the results (e.g. [0] => andi [1] => andi,micha [2] => andi,micha,peter etc.).
If the “exclusion” toggle was set I then removed all entries from the array which had more then the one “who” tag and displayed the resulting array.
Probably not very efficient but at least it worked for my small DB (~120’000 images)

The way I see it, the ‘who’ search should only apply to the sub-set of assets that have exactly 1 ‘who’ tag. It certainly would help if the asset table had various root tag counts (i.e. a WhoTagCount column, etc). But perhaps a subselect could achieve the same without actually storing the count as a discrete column?

EDIT: I was inspired to poke around in the sqlite db…

so I created a view as such:

CREATE VIEW WhoTagCount as select at.assetId, count(*) as WhoTagCount from assetTag at, tag t where at.tagId = t.id and _path like 'Who%' group by at.assetId

Then I joined that view in a search query as such:

select * from assetTag at, Tag t, WhoTagCount c where t.id = at.tagId and t._path like '%Genki%' and at.assetId = c.assetId and WhoTagCount = 1

This returned 3 assets out of 17 that have ‘Genki’ in them:

Converting the view to an actual table (or storing WhoTagCount in the asset table) would improve performance, however, it returns instant results on my smallish database of 80,000 assets as it is.