It is possible to search pictures for meta data which you have added (like keywords, comments and ratings), but you can also use search criteria like date, time, file size, file type, file name and path, ...
Right-click on a group in which you want to search (use the root group unless you know better) and select Search...
In the following dialog you can enter a search expression (an example to search for a string is given) and select some options regarding the display of the search result. The result is displayed as a new group, which in most regards can be used like any other group.
The search result is not updated automatically when underlying data has changed; you need to right click and use "refresh search result".
In order to simply search for a string contained in keywords and comments you can use the search query which is automatically filled in when adding a new search. Just enter the search word in between the given quotation marks (the cursor is already positioned there) and hit enter.
The dialog includes a box containing all keywords in the area you are searching. To input one of them, you can browse and select it using the mouse or simply begin to type it: the selection in the box will follow your input. Input two dots to auto-complete the current selection.
It is possible to search for whole keywords, their beginning, their end, or anywhere, because keywords are always separated by commas:
Match beginning of keyword: ",p.miller.j"
Match end of keyword: ".joe,"
Match whole keyword: ",p.miller.joe,"If you want to search for pictures which contain more than one word or expression, just append more search terms in quotation marks.
You can exclude pictures containing a certain expression by preceeding the expression with an exclamation mark, for example !"NotHere" will only show pictures which don't have NotHere somewhere in their metadata.
Additional characters preceeding the quotation mark define where to search:
pk keywords of this item and all items above, converted to lowercase k keywords of this item, converted to lowercase K keywords of this item pc comment of this item and all items above, converted to lowercase c comment of this item, converted to lowercase C comment of this item If you don't specify anything, it defaults to pkpc.
Besides comment and keywords, you can search pictures based on other attributes, listed in the following table:
key.num number of keywords file.size file size in bytes file.type file type: 1-picture, 2-movie, 0-other file.date file date ref.num number of references (how many times does this picture appear in the whole album) date date time time rate.num number of ratings rate.best best rating rate.worst worst rating rate.mean10 mean rating multiplied by ten rate.get the current users rating exif.t exposure time in microseconds exif.f f number multiplied by ten exif.iso iso number exif.date date To define a search condition, you need to compare attributes to something. Valid comparison operators are:
> greater than < less than == equal Each of the following examples of search terms define a condition which must be true for a picture to match. If you want several conditions to be true, just combine several terms.
file.type == 2
rate.best > 3
exif.iso > 800
date < 1985-04-15
time > 10:55:36Example for a combined search:
!c".p.miller.joe" ".p.miller.anne" date > 2012-01-23
The sections above described an easy to understand and use, but limited way of defining a search. It is possible to write more powerful search programs by using another syntax or by combining both of them.
The query is a program which is run on every picture below the group which you are searching. This program has to return a value, and if that value is different from zero, the picture is considered a hit.
This query language is something which even most programmers are not familiar with these days. It uses postfix notation and a stack instead of parentheses. Because of this it is easy to implement and can easily describe complex search expressions as optimized programs.
As an example, the search query : date 2011-04-10 > key.l str.find(".somestring,") pop * will be explained here step by step. The table shows three columns: position in stack, type of value, and commands producing that value.
First of all, the colon : indicates that this already is stack syntax and no translation from simple syntax is necessary.
The first instruction date puts (or pushes) the picture's date onto the stack:
[ 0] date date Afterwards a constant date is pushed by 2011-04-10:
[ 0] date 2011-04-10 [- 1] date date The instruction > takes the two latest values from the stack, compares them and pushes the result (one in case of the condition being true, zero otherwise):
[ 0] int date 2011-04-10 > key.l pushes a string containing the picture's keywords in lower case:
[ 0] string key.l [- 1] int date 2011-04-10 > str.find(".somestring,") takes the latest element from the stack (which must be a string), searches it for .somestring,, pushes the result (one in case of a hit, zero otherwise) and the string (in case it is needed for another search).
[ 0] string key.l [- 1] int key.l str.find [- 2] int date 2011-04-10 > We don't need the string again in this case, so it is taken from the stack (popped) using pop:
[ 0] int key.l str.find [- 1] int date 2011-04-10 > We want the search to return non-zero in case of both conditions being true (non-zero), so they are multiplied using *:
[ 0] int date 2011-04-10 > key.l str.find * After the program has finished, one value is left on the stack. If both conditions have been true (date greater than 2011-04-10 and keywords contain ".somestring,") it is non-zero, which means the picture is considered a hit.
Apart from the commands given below, you can push constant values onto the stack by just entering a number, date, or time. Example: ref.num 1 > date 2011-07-01 > *
The functions and operators listed in the sections above can also be used in the underlying query language.
[0] is the value on top of the stack, [-1] the value below and so on.
command | change of stack size | description |
---|---|---|
key | +1 | push keywords |
key.l | +1 | push lowercase keywords |
key.rmdup | 0 | cleans keywords of duplicates |
com | +1 | push comment |
com.l | +1 | push lowercase comment |
pcom.l | +1 | push lowercase comment of picture and all groups above |
pkey.l | +1 | push lowercase keywords of picture and all groups above |
name | +1 | push group name |
name.l | +1 | push lowercase group name |
id | +1 | push id string |
path | +1 | push picture path |
str.find("STRING") | +1 | pop [0] (which must be a string). If STRING is part of [0], 1 is pushed, 0 otherwise. Afterwards [0] is pushed again, because creating strings may be expensive. |
str.count("STRING") | +1 | similar to str.find, but returns the number of occurences. For example, you can use it to find pictures with a certain number of people shown (at least when using the proposed keyword syntax: str.count(",p.")). |
str.len | +1 | pop [0] (which must be a string). Its length is pushed. Afterwards [0] is pushed again, because creating strings may be expensive. |
str.cat | -1 | |
childof("STRING") | +1 | |
childof.r("STRING") | +1 | |
rate.set | -1 | pop value and set the current users rating to this value |
mark.set | -1 | pop value and mark picture if value is not zero |
mark.reset | -1 | pop value and unmark picture if value is not zero |
mark.copy | -1 | pop value and mark picture if value is not zero, unmark otherwise |
exif.make | +1 | push camera manufacturer's name |
exif.model | +1 | push camera model name |
dup | +1 | duplicate value of top of stack |
swap | 0 | swap [0] and [-1] |
pop | -1 | pop value |
! | 0 | if [0] is zero, change it to one, otherwise to zero |
+ | -1 | pop [0] and [-1] and push their sum |
- | -1 | pop [0] and [-1] and push their difference |
* | -1 | pop [0] and [-1] and push their product |
min | -1 | pop [0] and [-1] and push the smaller one |
max | -1 | pop [0] and [-1] and push the bigger one |
true | 0 | if [0] is not zero, exit from program and return 1.
Can be used in long programs to end them early in case
their return value is already known, for example in a long
row of anded or expensive expressions one may quit in case only one of
them is false. Simple: date "2009-10-23" < pcom.l str.find("bla") pop * Maybe faster in case of long strings: date "2009-10-23" < ! false ! pcom.l str.find("bla") pop * |
false | 0 | if [0] is not zero, exit from program and return 0. See true |